version 1.2, 2011/12/28 22:09:44
|
version 1.32, 2024/12/31 19:28:29
|
Line 1
|
Line 1
|
# The LearningOnline Network with CAPA |
# The LearningOnline Network with CAPA |
# Routines for configuring blocking to collaborative functions, and specific |
# Routines for configuring blocking of access to collaborative functions, |
# resources during an exam |
# and specific resources during an exam |
# |
# |
# $Id$ |
# $Id$ |
# |
# |
Line 26
|
Line 26
|
# |
# |
# http://www.lon-capa.org/ |
# http://www.lon-capa.org/ |
# |
# |
############################################################### |
############################################################## |
############################################################## |
############################################################## |
|
|
=pod |
=pod |
Line 44 lonblockingmenu provides an interface fo
|
Line 44 lonblockingmenu provides an interface fo
|
This module is used to configure blocking of access to collaborative tools |
This module is used to configure blocking of access to collaborative tools |
and/or resources during an exam. |
and/or resources during an exam. |
|
|
|
=head1 OVERVIEW |
|
|
|
To support high-stakes testing, LON-CAPA provides Coordinators with the |
|
ability to disable communication and collaborative features within the |
|
system for the duration of an exam. |
|
|
|
Features which can be disabled include: |
|
(a) those which a student could use to communicate with another student. |
|
Messaging, discussion, chat, blogs, and some functionality in groups fall |
|
into this category. |
|
(b) those which a student could use to access materials prepared by the |
|
student in advance of an exam, (e.g., for use during an online exam, to |
|
gain an unfair advantage). Blogs and portfolio fall into this category. |
|
(c) those which a student could use to display or save content within |
|
the course itself (outside the exam folder). Printouts and resources |
|
fall into this category. |
|
|
|
For communication blocking to be truly effective in preventing unwanted |
|
communication, or access to online materials, online testing needs to |
|
take place in a lab setting where use of tools outside LON-CAPA, and use |
|
of web sites beyond LON-CAPA are unavailable. |
|
|
|
Access to specified folder(s) and/or resources in the course contents |
|
can be restricted for the duration of an exam. |
|
|
|
Exam blocks are of two types: |
|
(a) Blocks with a defined start and end date. |
|
(b) Blocks associated with a timed interval set for a specific folder, |
|
or resource. |
|
|
|
When a student attempts to use a collaboration or communication feature |
|
which is currently blocked, information will be available about the |
|
duration of the block, and the identity of the Course Coordinator who |
|
set the block. |
|
|
|
Although LON-CAPA communication can be blocked during an exam, course |
|
personnel with the 'evb' (evade blocking) privilege will continue to |
|
receive LON-CAPA messages sent from students in a course with an active |
|
block on messaging. Students will not be able to view messages sent by |
|
other students in the same course for the duration of the blocking event. |
|
|
|
Because students may be enrolled in more than one LON-CAPA course at a time |
|
it is important to use reasonable time windows for blocking events, or, in |
|
the case of blocks triggered by clicking a button to start a timed quiz, |
|
quiz durations that are of limited duration. This is especially important |
|
when blocking prtfolio access, as other courses may require students to use |
|
the portfolio as a mechanism for submitting assignments. |
|
|
|
Information about blocks in a course will be cached for 10 minutes, so, |
|
as with parameters set for resources, it can take up to 10 minutes for |
|
new blocks, or changes to existing blocks, to propagate to other servers. |
|
|
|
Changes to existing blocks on the server hosting your current session |
|
are available immediately, as cached data on blocks is devalidated |
|
automatically on the current server whenever a change is made to a |
|
block (including deletion), or when a new block is added. |
|
|
=head1 INTERNAL SUBROUTINES |
=head1 INTERNAL SUBROUTINES |
|
|
=over |
=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 |
|
parameters set in a course. |
|
|
|
Inputs: 2 (optional) |
|
$cdom - course's domain |
|
|
|
$cnum - course's ID |
|
|
|
Output: 1 Hash |
|
nested hashes containing information about timed interval |
|
parameters in course). Top level keys are type: course, |
|
map, resource. Next inner keys are map or symb. Next |
|
inner keys are scope (all, section, group, users). |
|
Values are interval (in seconds). |
|
|
=item &blockstore() |
=item &blockstore() |
|
|
|
Stores changes to exam blocks in comm_block.db file for course. |
|
Processes deletions, modifications and additions. |
|
|
|
Inputs: 4 |
|
$r = request object |
|
|
|
$crstype - Container type: Course or Community. |
|
|
|
$blockcount - Total number of blocking events in course. |
|
|
|
$currblockrecs - Ref to hash of current blocks in course. |
|
|
|
Outputs: 2 |
|
$changestotal - Total number of changes made. |
|
|
|
$output - Information about changes made. |
|
|
|
|
=item &get_dates_from_form() |
=item &get_dates_from_form() |
|
|
|
Extract start and end dates from web form input for blocks with |
|
defined start/end time. |
|
|
|
Inputs: 1 - $item - numeric ID of current block. |
|
|
|
Outputs: 2 - $startdate, $enddate (UNIX times for start and end times |
|
for blocks with defined start/end |
|
|
|
|
=item &get_blockdates() |
=item &get_blockdates() |
|
|
|
Retrieves contents of comm_block.db file for a course. |
|
|
|
Inputs: 1 - $records - reference to hash to contain blocks |
|
|
|
Outputs: 1 - $blockcount - number of blocks |
|
|
|
Side Effects: populates records hashref. |
|
|
|
|
=item &get_block_choices() |
=item &get_block_choices() |
|
|
|
Extract information from web form about which communication/ |
|
collaboration features are to be blocked, for a particular event, |
|
and also which content areas will have access blocked for the |
|
duration of the block. |
|
|
|
Inputs: 3 |
|
- $item - numeric ID of current block |
|
|
|
- $map_ref - reference to hash mapping numeric IDs to map urls |
|
|
|
- $symb_ref - reference to hash mapping numeric IDs to symbs |
|
|
|
Outputs: 2 |
|
- $blocktypes - reference to hash of features to be blocked |
|
|
|
- $blockdocs - boolean - 0 if no blocking of content, 1 if blocking |
|
of content access |
|
|
|
|
|
=item &check_release_required() |
|
|
|
Update LON-CAPA version requirements for course if blocked items |
|
(content) or blocking type (triggered by student starting timer) |
|
require specific LON-CAPA version (i.e., 2.11). |
|
|
|
Inputs: 3 - $value - type of constraint (currently: 'docs', 'printout' or 'timer'), |
|
$chomemajor - course's home server LON-CAPA major version number. |
|
$chomeminor - course's home server LON-CAPA minor version number. |
|
|
|
Outputs: 2 - status ('ok' or 'fail') and LON-CAPA version needed. |
|
|
|
=over |
|
|
|
A status of 'fail' will be returned if the |
|
LON-CAPA version installed on the course's |
|
home server is older than the version |
|
requirement for the blocking type. |
|
For a trigger type event, the requested |
|
blocking event will not be added if |
|
the course's home server version is old to |
|
support that type of block. |
|
|
|
=back |
|
|
|
Side Effects: &update_released_required() called in lonnet, if |
|
course's home server version is requied version or |
|
newer; will update version requirements for course to |
|
a more recent version requirement than currently in |
|
effect. |
|
|
|
|
=item &display_blocker_status() |
=item &display_blocker_status() |
|
|
|
Generates web form elements used to display, cancel, or modify |
|
existing blocking events. |
|
|
|
Inputs: 8 |
|
- $r - Apache request object |
|
|
|
- $records - Reference to hash of current blocks |
|
|
|
- $ltext - Reference to hash of phrases (localized) |
|
|
|
- $intervals - Reference to hash of parameters for timed intervals |
|
|
|
- $navmap - navmaps object. |
|
|
|
- $errormsg - error message for display, if navmaps object |
|
could not be instantiated |
|
|
|
- $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. |
|
|
|
=item &convlim() |
|
|
|
Convert a time interval used for a timed quiz (in seconds) to |
|
days, hours. minutes and seconds. |
|
|
|
Inputs: 1 - $timelimit - time interval in seconds |
|
|
|
Outputs: 1 - $output - time in format: DD days, HH hours, MM minutes, SS seconds |
|
|
|
|
=item &display_addblocker_table() |
=item &display_addblocker_table() |
|
|
|
Generate web form elements used to define a new blocking event. |
|
|
|
Inputs: 6 |
|
- $r - Apache resource object |
|
|
|
- $parmcount - current ID for block (same as number of current blocks, |
|
block IDs in web form have zero-based index) |
|
|
|
- $ltext - reference to hash of phrases (localized) |
|
|
|
- $intervals - Reference to hash of parameters for timed intervals |
|
|
|
- $navmap - navmaps object |
|
|
|
- $errormsg - error message for display, if navmaps object |
|
could not be instantiated |
|
|
|
Outputs: None |
|
|
|
Side Effects: prints web form elements (in a table) for adding a new block. |
|
|
|
|
|
=item &blocker_checkboxes() |
|
|
|
Generates web form elements in a table for checkboxes used to indicate |
|
which types of communication/collaboration and/or content should be blocked. |
|
|
|
Inputs: 4 |
|
- $parmcount - numeric ID of current block |
|
|
|
- $blocks - reference to hash of functionalities to block |
|
|
|
- $jschg - text of javascript call to execute when checkbox clicked |
|
use within a box via 'onclick="$jchg"' |
|
|
|
- $lookups - reference to hash to map urls or symbs to numeric IDs |
|
used to populate hodden form elements containing list |
|
of resources and folders with access blocking currently set. |
|
|
|
Output: 1 - HTML for table of checkboxes for current block |
|
|
|
|
|
=item &create_interval_form() |
|
|
|
Creates web form elements used to select one of the defined timed interval |
|
items in the course for use in an exam block of type: "Triggered by |
|
Activating Timer". |
|
|
|
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). |
|
|
|
- $jschg - text of javascript call to execute when radiobutton clicked |
|
use within a box via 'onclick="$jchg"' |
|
|
|
- $itemname - name/scope of current interval used for this block |
|
|
|
- $iteminfo - Expandable/collapsible block showing which users are |
|
able to activate the timer using the current trigger item. |
|
|
|
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 |
|
trigger for exam block. |
|
|
|
Inputs: 1 - $parmcount - numericID of exam block in web form. |
|
|
|
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 |
|
item identified as an item with an interval timer set. |
|
|
|
Inputs: 3 |
|
- $type - map or resource |
|
|
|
- $item - map URL or resource symb |
|
|
|
- $navmap - navmaps object |
|
|
|
Outputs: 1 - HTML containing hierarchy of folders/subfolders (raquo entity separated). |
|
|
|
|
=item &blocktype_text() |
=item &blocktype_text() |
|
|
=back |
Inputs: None |
|
|
|
Output: 2 |
|
- $typeorder - reference to array of blockable communication/collaboration/content |
|
|
|
- $types -reference to hash of descriptions (localized) of blockable types. |
|
|
|
|
|
=item &blockingmenu_javascript() |
|
|
|
Create Javascript used to launch pop-up used for content selection, and to |
|
toggle visibility of a number of expandable/collapsible divs. |
|
|
|
Inputs: 1 - $blockcount - Total number of blocks in course's comm_block.db |
|
database file. |
|
|
|
Output: 1 - Javascript (with <script></script> tags) for functions used to: |
|
(a) launch pop-up window for selection of course content to which |
|
access could be blocked. |
|
(b) toggle visibility of a number of divs: |
|
|
|
=over |
|
|
|
=item * for block type - defined dates or timer activated |
|
|
|
=item * for action to take -- add or modify block |
|
|
|
=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 |
=cut |
|
|
Line 73 use Apache::lonnet;
|
Line 449 use Apache::lonnet;
|
use Apache::Constants qw(:common :http); |
use Apache::Constants qw(:common :http); |
use Apache::loncommon(); |
use Apache::loncommon(); |
use Apache::lonhtmlcommon(); |
use Apache::lonhtmlcommon(); |
|
use Apache::lonparmset(); |
|
use Apache::loncourserespicker(); |
use HTML::Entities(); |
use HTML::Entities(); |
use Apache::lonlocal; |
use Apache::lonlocal; |
use lib '/home/httpd/lib/perl/'; |
use lib '/home/httpd/lib/perl/'; |
use LONCAPA qw(:DEFAULT :match); |
use LONCAPA qw(:DEFAULT :match); |
|
|
|
my $registered_cleanup; |
|
my $modified_courses; |
|
|
sub handler { |
sub handler { |
my $r=shift; |
my $r=shift; |
|
|
Line 98 sub handler {
|
Line 479 sub handler {
|
|
|
# ----------------------------------------------------------- Permissions check |
# ----------------------------------------------------------- Permissions check |
|
|
unless ((!&Apache::lonnet::allowed('dcm',$env{'request.course.id'})) || |
my ($readonly,$allowed) = &get_permission(); |
(!&Apache::lonnet::allowed('dcm',$env{'request.course.id'}. |
unless ($allowed) { |
'/'.$env{'request.course.sec'}))) { |
$env{'user.error.msg'}= |
|
"/adm/setblock:dcm:0:0:Cannot view/set blocking of communications in a course"; |
return HTTP_NOT_ACCEPTABLE; |
return HTTP_NOT_ACCEPTABLE; |
} |
} |
|
|
# -----------------------------Get action and calling context from query string |
# -----------------------------Get action and calling context from query string |
|
|
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['action','caller']); |
$registered_cleanup=0; |
|
@{$modified_courses}=(); |
|
|
|
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, |
|
['action','caller','block']); |
|
|
|
my $crstype = &Apache::loncommon::course_type(); |
|
my $action = $env{'form.action'}; |
|
my %records = (); |
|
my $blockcount = 0; |
|
|
|
# ------------------------------------------------------ Retrieve current blocks |
|
$blockcount = &get_blockdates(\%records); |
|
|
|
# -------------------- Generate display for pop-up of Maps and Resources blocked |
|
if ($action eq 'showdocs') { |
|
my ($navmap,$errormsg) = |
|
&Apache::loncourserespicker::get_navmap_object($crstype,'examblock'); |
|
if (ref($navmap)) { |
|
my (%blockedmaps,%blockedresources); |
|
if ($env{'form.block'} =~ /^\d+$/) { |
|
my @currblocks = sort(keys(%records)); |
|
my $block = $currblocks[$env{'form.block'}]; |
|
if (($block ne '') && (ref($records{$block}) eq 'HASH')) { |
|
if (ref($records{$block}{'blocks'}) eq 'HASH') { |
|
if (ref($records{$block}{'blocks'}{'docs'}) eq 'HASH') { |
|
if (ref($records{$block}{'blocks'}{'docs'}{'maps'}) eq 'HASH') { |
|
%blockedmaps = %{$records{$block}{'blocks'}{'docs'}{'maps'}}; |
|
} |
|
if (ref($records{$block}{'blocks'}{'docs'}{'resources'}) eq 'HASH') { |
|
%blockedresources = %{$records{$block}{'blocks'}{'docs'}{'resources'}}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
$r->print(&Apache::loncourserespicker::create_picker($navmap, |
|
'examblock','resourceblocks',$crstype, |
|
\%blockedmaps,\%blockedresources, |
|
$env{'form.block'},'','',undef,undef,undef, |
|
$readonly)); |
|
} else { |
|
$r->print($errormsg); |
|
} |
|
return OK; |
|
} |
|
|
# ----------------------------------------------------------------- Breadcrumbs |
# -------------------------- Store changes and retrieve latest block information |
|
my $storeresult; |
|
unless ($readonly) { |
|
if ($env{'form.action'} eq 'store') { |
|
(my $numchanges,$storeresult) = &blockstore($r,$crstype,$blockcount,\%records); |
|
if ($numchanges > 0) { |
|
$blockcount = &get_blockdates(\%records); |
|
} |
|
} |
|
} |
|
|
|
# ------------------------------------------------------------------ Breadcrumbs |
&Apache::lonhtmlcommon::clear_breadcrumbs(); |
&Apache::lonhtmlcommon::clear_breadcrumbs(); |
if ($env{'form.caller'} eq 'email') { |
if ($env{'form.caller'} eq 'email') { |
&Apache::lonhtmlcommon::add_breadcrumb |
&Apache::lonhtmlcommon::add_breadcrumb |
Line 123 sub handler {
|
Line 560 sub handler {
|
} |
} |
&Apache::lonhtmlcommon::add_breadcrumb |
&Apache::lonhtmlcommon::add_breadcrumb |
({href=>'/adm/setblock', |
({href=>'/adm/setblock', |
text=>'Blocking communication/resource access'}); |
text=>'Blocking communication/content access'}); |
|
|
$r->print(&Apache::loncommon::start_page('Blocking communication/resource access'). |
my $js = &blockingmenu_javascript($blockcount). |
&Apache::lonhtmlcommon::breadcrumbs('Blocking communication/resource access')); |
&details_javascript(); |
|
|
# ----------------------------------------------------------- Permissions check |
$r->print( |
|
&Apache::loncommon::start_page('Blocking communication/content access',$js). |
|
&Apache::lonhtmlcommon::breadcrumbs('Blocking communication/content access')); |
|
|
my $usertype; |
my $usertype; |
my $crstype = &Apache::loncommon::course_type(); |
|
if ($crstype eq 'Community') { |
if ($crstype eq 'Community') { |
$usertype = 'members'; |
$usertype = 'members'; |
} else { |
} else { |
$usertype = 'students'; |
$usertype = 'students'; |
} |
} |
my $lctype = lc($crstype); |
my $lctype = lc($crstype); |
my %lt=&Apache::lonlocal::texthash( |
my %lt=&Apache::lonlocal::texthash ( |
'cbds' => 'Communication blocking during scheduled exams', |
'cbds' => 'Blocking communication and/or content access during exams', |
'desc' => "You can use communication blocking to prevent $usertype enrolled in this $lctype from displaying LON-CAPA messages sent by other $usertype during an online exam. As blocking of communication could potentially interrupt legitimate communication between $usertype who are also both enrolled in a different LON-CAPA course or community, please be careful that you select the correct start and end times for your scheduled exam when setting or modifying these parameters.", |
'prev' => "For the duration of an exam, or a timed quiz, students in this course can be prevented from:", |
'mecb' => 'Modify existing communication blocking periods', |
'flow' => "For the duration of an exam, or a timed quiz, event-driven interruptions to a student's workflow can be suppressed:", |
'ncbc' => 'No communication blocks currently saved', |
'blca' => "Blocks can potentially interrupt legitimate communication between $usertype who are also both enrolled in a different LON-CAPA $lctype.", |
'stor' => 'Save', |
'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:", |
|
'addn' => 'Add new blocking event', |
|
'mexb' => 'Modify existing blocking event(s)', |
|
'ncbc' => 'There are no blocking events currently saved.', |
|
'stor' => 'Save', |
); |
); |
|
|
my %ltext = &Apache::lonlocal::texthash( |
my %ltext = &Apache::lonlocal::texthash( |
'dura' => 'Duration', |
'type' => 'Type', |
|
'defs' => 'Defined Start/End', |
|
'trig' => 'Triggered by Activating Timer', |
'setb' => 'Set by', |
'setb' => 'Set by', |
'even' => 'Event', |
'even' => 'Event', |
'blck' => 'Blocked?', |
'blck' => 'Blocked?', |
'actn' => 'Action', |
|
'star' => 'Start', |
'star' => 'Start', |
'endd' => 'End' |
'endd' => 'End', |
|
'chda' => 'Choose dates', |
|
'chtr' => 'Choose trigger', |
|
'when' => 'When using defined start/end times for an event, please set dates carefully.', |
|
'yes' => 'Yes', |
|
'no' => 'No', |
); |
); |
|
|
$r->print('<h3>'.$lt{'cbds'}.'</h3>'); |
$r->print('<h3>'.$lt{'cbds'}.'</h3>'); |
|
|
|
# ---------------------------------------------------- Get Time Limit parameters |
|
my %intervals = &get_timed_items(); |
|
|
|
# -------------------------------------------- Display information about changes |
if ($env{'form.action'} eq 'store') { |
if ($env{'form.action'} eq 'store') { |
&blockstore($r); |
$r->print($storeresult); |
|
} else { |
|
$r->print( |
|
$lt{'prev'}. |
|
'<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, 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("displaying $lctype content indexed 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>' |
|
); |
} |
} |
|
|
$r->print($lt{'desc'}.'<br /><br /> |
# ------------------------ Choose between modifying existing block or adding new |
<form name="blockform" method="post" action="/adm/setblock?action=store"> |
$r->print('<form name="blockform" method="post" action="/adm/setblock?action=store">'); |
'); |
|
|
|
$r->print('<h4>'.$lt{'mecb'}.'</h4>'); |
unless ($readonly) { |
my %records = (); |
if ($blockcount > 0) { |
my $blockcount = 0; |
$r->print(<<"END"); |
my $parmcount = 0; |
<div class="LC_left_float"> |
&get_blockdates(\%records,\$blockcount); |
<fieldset><legend>$lt{'actt'}</legend> |
if ($blockcount > 0) { |
<span class="LC_nobreak"> |
$parmcount = &display_blocker_status($r,\%records,\%ltext); |
<label><input type="radio" name="blockaction" value="modify" id="modifyaction" |
|
onclick="toggleAddModify();" checked="checked" />$lt{'mexb'}</label> |
|
</span> |
|
<br /> |
|
<span class="LC_nobreak"> |
|
<label><input type="radio" name="blockaction" value="add" id="addaction" |
|
onclick="toggleAddModify();" />$lt{'addn'}</label> |
|
</span> |
|
</fieldset> |
|
</div> |
|
<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" />'); |
|
} |
|
} |
|
my ($navmap,$errormsg) = |
|
&Apache::loncourserespicker::get_navmap_object($crstype,'examblock'); |
|
|
|
# --------------------------------------------- Interface for adding a new block |
|
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 { |
} else { |
$r->print($lt{'ncbc'}.'<br /><br />'); |
&display_blocker_status($r,\%records,\%ltext,\%intervals, |
|
$navmap,$errormsg,$blockcount,$readonly); |
} |
} |
&display_addblocker_table($r,$parmcount,\%ltext); |
unless ($readonly) { |
my $end_page=&Apache::loncommon::end_page(); |
$r->print(<<"END"); |
$r->print(<<"END"); |
|
<br /> |
<br /> |
<input type="hidden" name="blocktotal" value="$blockcount" /> |
|
<input type ="submit" value="$lt{'stor'}" /> |
<input type ="submit" value="$lt{'stor'}" /> |
</form> |
|
$end_page |
|
END |
END |
|
} |
$r->print(&Apache::loncommon::end_page()); |
$r->print('</form>'. |
|
&Apache::loncommon::end_page()); |
return OK; |
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); |
|
if ($cdom eq '' || $cnum eq '') { |
|
$cid = $env{'request.course.id'}; |
|
$cdom = $env{'course.'.$cid.'.domain'}; |
|
$cnum = $env{'course.'.$cid.'.num'}; |
|
} else { |
|
$cid = $cdom.'_'.$cnum; |
|
} |
|
if ($cid eq '') { |
|
return %intervals; |
|
} |
|
my $resourcedata=&Apache::lonparmset::readdata($cnum,$cdom); |
|
if (ref($resourcedata) eq 'HASH') { |
|
foreach my $key (keys(%{$resourcedata})) { |
|
if ($key =~ /^\Q$cid\E(.*)\.0\.interval$/) { |
|
my $middle = $1; |
|
if ($middle eq '') { |
|
$intervals{'course'}{'all'} = $resourcedata->{$key}; |
|
} elsif ($middle =~ /^\.\[(\w+)\]$/) { |
|
$intervals{'course'}{'secgrp'}{$1} = $resourcedata->{$key}; |
|
} elsif ($middle =~ /^\.\[useropt\:($match_username\:$match_domain)\]$/) { |
|
$intervals{'course'}{'users'}{$1} = $resourcedata->{$key}; |
|
} elsif ($middle =~ /^\.(.+)\Q___(all)\E$/) { |
|
my $inner = $1; |
|
if ($inner =~ /^\[(\w+)\]\.([^\]]+)$/) { |
|
$intervals{'map'}{$2}{'secgrp'}{$1} = $resourcedata->{$key}; |
|
} elsif ($inner =~ /^\[useropt\:($match_username\:$match_domain)\]\.([^\]]+)$/) { |
|
$intervals{'map'}{$2}{'users'}{$1} = $resourcedata->{$key}; |
|
} else { |
|
$intervals{'map'}{$inner}{'all'} = $resourcedata->{$key}; |
|
} |
|
} elsif ($middle =~ /^\.\[(\w+)\]\.([^\]]+)$/) { |
|
$intervals{'resource'}{$2}{'secgrp'}{$1} = $resourcedata->{$key}; |
|
} elsif ($middle =~ /^\.\[useropt\:($match_username\:$match_domain)\]\.([^\]]+)$/) { |
|
$intervals{'resource'}{$2}{'users'}{$1} = $resourcedata->{$key}; |
|
} else { |
|
my ($symb) = ($middle =~ /^\.(.+)$/); |
|
$intervals{'resource'}{$symb}{'all'} = $resourcedata->{$key}; |
|
} |
|
} |
|
} |
|
} |
|
return %intervals; |
|
} |
|
|
sub blockstore { |
sub blockstore { |
my $r = shift; |
my ($r,$crstype,$blockcount,$currblockrecs) = @_; |
my %lt=&Apache::lonlocal::texthash( |
my %lt=&Apache::lonlocal::texthash( |
'tfcm' => 'The following changes were made', |
'tfcm' => 'The following changes were made', |
'ncwm' => 'No changes were made.' |
'ncwm' => 'No changes were made.', |
|
'unna' => 'Unable to retrieve contents of course.', |
); |
); |
my %adds = (); |
my %adds = (); |
my %removals = (); |
my %removals = (); |
Line 202 sub blockstore {
|
Line 773 sub blockstore {
|
my $modtotal = 0; |
my $modtotal = 0; |
my $canceltotal = 0; |
my $canceltotal = 0; |
my $addtotal = 0; |
my $addtotal = 0; |
|
my $changestotal = 0; |
|
my $addtimer = 0; |
my %blocking = (); |
my %blocking = (); |
$r->print('<h3>'.$lt{'head'}.'</h3>'); |
my (%map_url,%resource_symb,%titles,$output); |
foreach my $envkey (keys(%env)) { |
$output = '<h3>'.$lt{'head'}.'</h3>'; |
if ($envkey =~ m/^form\.modify_(\d+)$/) { |
if ($env{'form.blockaction'} eq 'modify') { |
$adds{$1} = $1; |
foreach my $envkey (keys(%env)) { |
$removals{$1} = $1; |
if ($envkey =~ m/^form\.action_(\d+)$/) { |
$modtotal ++; |
if ($env{$envkey} eq 'modify') { |
} elsif ($envkey =~ m/^form\.cancel_(\d+)$/) { |
$adds{$1} = 1; |
$cancels{$1} = $1; |
$removals{$1} = 1; |
unless ( defined($removals{$1}) ) { |
} elsif ($env{$envkey} eq 'cancel') { |
$removals{$1} = $1; |
$cancels{$1} = $1; |
$canceltotal ++; |
unless ( defined($removals{$1}) ) { |
} |
$removals{$1} = 1; |
} elsif ($envkey =~ m/^form\.add_(\d+)$/) { |
$canceltotal ++; |
$adds{$1} = $1; |
} |
$addtotal ++; |
} |
|
} |
} |
} |
|
} elsif ($env{'form.blockaction'} eq 'add') { |
|
$adds{$blockcount} = 1; |
|
} |
|
my ($navmap,$errormsg) = |
|
&Apache::loncourserespicker::get_navmap_object($crstype,'examblock'); |
|
unless (ref($navmap)) { |
|
$output = $lt{'unna'}.' '.$lt{'ncwm'}.'</br>'; |
|
return ($changestotal,$output); |
} |
} |
|
&Apache::loncourserespicker::enumerate_course_contents($navmap,\%map_url,\%resource_symb,\%titles,'examblock'); |
|
my $do_releasereq_update; |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $chome = $env{'course.'.$env{'request.course.id'}.'.home'}; |
|
my $chostname = &Apache::lonnet::hostname($chome); |
|
my ($chomemajor,$chomeminor) = |
|
split(/\./,&Apache::lonnet::get_server_loncaparev($cdom,$chome)); |
|
|
|
|
foreach my $key (keys(%removals)) { |
foreach my $key (keys(%removals)) { |
my $hashkey = $env{'form.key_'.$key}; |
my $hashkey = $env{'form.key_'.$key}; |
&Apache::lonnet::del('comm_block',["$hashkey"], |
if ($hashkey =~ /firstaccess____/) { |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$do_releasereq_update = 1; |
$env{'course.'.$env{'request.course.id'}.'.num'} |
} |
); |
if (ref($currblockrecs->{$hashkey}) eq 'HASH') { |
|
if (ref($currblockrecs->{$hashkey}->{'blocks'}) eq 'HASH') { |
|
foreach my $type ('docs','printout') { |
|
if (exists($currblockrecs->{$hashkey}->{'blocks'}->{$type})) { |
|
$do_releasereq_update = 1; |
|
} |
|
} |
|
} |
|
} |
|
&Apache::lonnet::del('comm_block',["$hashkey"],$cdom,$cnum); |
|
} |
|
if ($do_releasereq_update) { |
|
push(@{$modified_courses},[$cdom,$cnum,$chome,$crstype]); |
|
unless ($registered_cleanup) { |
|
my $handlers = $r->get_handlers('PerlCleanupHandler'); |
|
$r->set_handlers('PerlCleanupHandler' => [\&update_releasereq,@{$handlers}]); |
|
$registered_cleanup=1; |
|
} |
} |
} |
foreach my $key (keys(%adds)) { |
foreach my $key (keys(%adds)) { |
unless ( defined($cancels{$key}) ) { |
unless ( defined($cancels{$key}) ) { |
my ($newstart,$newend) = &get_dates_from_form($key); |
my ($newkey,$status,$needsrelease);; |
my $newkey = $newstart.'____'.$newend; |
if ($env{'form.firstaccess_'.$key}) { |
my $blocktypes = &get_block_choices($key); |
my $interval = |
$blocking{$newkey} = { |
&HTML::Entities::decode($env{'form.firstaccess_'.$key}); |
|
if ($interval ne '') { |
|
if ($interval eq 'course') { |
|
$newkey = 'firstaccess____'.$interval; |
|
} elsif ($interval =~ /___\d+___/) { |
|
my ($map,$resid,$url) = |
|
&Apache::lonnet::decode_symb($interval); |
|
if (&Apache::lonnet::is_on_map($url)) { |
|
$newkey = 'firstaccess____'.$interval; |
|
} |
|
} elsif (&Apache::lonnet::is_on_map($interval)) { |
|
$newkey = 'firstaccess____'.$interval; |
|
} |
|
if ($newkey ne '') { |
|
unless (defined($removals{$key})) { |
|
($status,$needsrelease) = &check_release_required('timer',$chomemajor,$chomeminor); |
|
if ($status eq 'fail') { |
|
$newkey = ''; |
|
$output .= '<p class="LC_warning">'. |
|
&mt('Triggering of blocking events not allowed for [_1]', |
|
&escape($env{'form.title_'.$key})).'<br />'; |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
my ($newstart,$newend) = &get_dates_from_form($key); |
|
$newkey = $newstart.'____'.$newend; |
|
} |
|
if ($status eq 'fail') { |
|
$output .= &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).', |
|
$chomemajor.'.'.$chomeminor,$chostname,$needsrelease).'</p>'; |
|
} |
|
if ($newkey ne '') { |
|
my ($blocktypes,$blockdocs) = |
|
&get_block_choices($key,\%map_url,\%resource_symb); |
|
if (ref($blocktypes) eq 'HASH') { |
|
if ($blocktypes->{'printout'} eq 'on') { |
|
($status,$needsrelease) = &check_release_required('printout',$chomemajor,$chomeminor); |
|
if ($status eq 'fail') { |
|
$blocktypes->{'printout'} = 'off'; |
|
$output .= '<p class="LC_warning">'. |
|
&mt('Printout blocking not allowed for [_1]', |
|
&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); |
|
if ($status eq 'fail') { |
|
delete($blocktypes->{'docs'}); |
|
$output .= '<p class="LC_warning">'. |
|
&mt('Content blocking not allowed for [_1]', |
|
&escape($env{'form.title_'.$key})).'<br />'; |
|
} |
|
} |
|
$blocking{$newkey} = { |
setter => $env{'user.name'}.':'.$env{'user.domain'}, |
setter => $env{'user.name'}.':'.$env{'user.domain'}, |
event => &escape($env{'form.title_'.$key}), |
event => &escape($env{'form.title_'.$key}), |
blocks => $blocktypes, |
blocks => $blocktypes, |
}; |
}; |
|
if (exists($removals{$key})) { |
|
$modtotal ++; |
|
} else { |
|
$addtotal ++; |
|
} |
|
} else { |
|
if ($env{'form.toggle_'.$key} eq 'timer') { |
|
unless ($status eq 'fail') { |
|
$output .= '<p class="LC_warning">'. |
|
&mt('Invalid trigger for new blocking event'). |
|
'</p>'; |
|
} |
|
} else { |
|
$output .= '<p class="LC_warning">'. |
|
&mt('No date range found for new blocking event'). |
|
'</p>'; |
|
} |
|
} |
} |
} |
} |
} |
if ($addtotal + $modtotal > 0) { |
if ($addtotal + $modtotal > 0) { |
Line 246 sub blockstore {
|
Line 946 sub blockstore {
|
$env{'course.'.$env{'request.course.id'}.'.num'} |
$env{'course.'.$env{'request.course.id'}.'.num'} |
); |
); |
} |
} |
my $chgestotal = $canceltotal + $modtotal + $addtotal; |
$changestotal = $canceltotal + $modtotal + $addtotal; |
if ($chgestotal > 0) { |
if ($changestotal > 0) { |
$r->print($lt{'tfcm'}.'<ul>'); |
&Apache::lonnet::devalidate_cache_new('comm_block', |
|
$env{'request.course.id'}); |
|
$output .= $lt{'tfcm'}.'<ul>'; |
if ($canceltotal > 0) { |
if ($canceltotal > 0) { |
$r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] removed.',$canceltotal).'</li>'); |
$output .= '<li>'. |
|
&mt('[quant,_1,blocking event was,blocking events were] removed.', |
|
$canceltotal). |
|
'</li>'; |
} |
} |
if ($modtotal > 0) { |
if ($modtotal > 0) { |
$r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] modified.',$modtotal).'</li>'); |
$output .= '<li>'. |
|
&mt('[quant,_1,blocking event was,blocking events were] modified.', |
|
$modtotal). |
|
'</li>'; |
} |
} |
if ($addtotal > 0) { |
if ($addtotal > 0) { |
$r->print('<li>'.&mt('[quant,_1,communication blocking period was,communication blocking periods were] added.',$addtotal).'</li>'); |
$output .= '<li>'. |
|
&mt('[quant,_1,blocking event was,blocking events were] added.', |
|
$addtotal). |
|
'</li>'; |
} |
} |
$r->print('</ul>'); |
$output .= '</ul>'; |
} else { |
} else { |
$r->print($lt{'ncwm'}); |
$output .= $lt{'ncwm'}; |
} |
} |
$r->print('<br />'); |
$output .= '<br />'; |
return; |
return ($changestotal,$output); |
|
} |
|
|
|
sub update_releasereq { |
|
my $readmap = 1; |
|
my $getrelreq = 1; |
|
if (ref($modified_courses) eq 'ARRAY') { |
|
foreach my $item (@{$modified_courses}) { |
|
if (ref($item) eq 'ARRAY') { |
|
my ($cdom,$cnum,$chome,$crstype) = @{$item}; |
|
&Apache::lonrelrequtils::modify_course_relreq(undef,undef,$cnum,$cdom, |
|
$chome,$crstype,$cdom.'_'.$cnum, |
|
$readmap,$getrelreq); |
|
} |
|
} |
|
$modified_courses = []; |
|
} |
|
return OK; |
} |
} |
|
|
sub get_dates_from_form { |
sub get_dates_from_form { |
Line 274 sub get_dates_from_form {
|
Line 1002 sub get_dates_from_form {
|
} |
} |
|
|
sub get_blockdates { |
sub get_blockdates { |
my ($records,$blockcount) = @_; |
my ($records) = @_; |
$$blockcount = 0; |
my $blockcount = 0; |
%{$records} = &Apache::lonnet::dump('comm_block', |
%{$records} = &Apache::lonnet::dump('comm_block', |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.domain'}, |
$env{'course.'.$env{'request.course.id'}.'.num'} |
$env{'course.'.$env{'request.course.id'}.'.num'} |
); |
); |
$$blockcount = keys(%{$records}); |
$blockcount = keys(%{$records}); |
|
|
if ((keys(%{$records}))[0] =~ /^error: 2 /) { |
if ((keys(%{$records}))[0] =~ /^error: 2 /) { |
$$blockcount = 0; |
$blockcount = 0; |
} |
} |
|
return $blockcount; |
} |
} |
|
|
sub get_block_choices { |
sub get_block_choices { |
my $item = shift; |
my ($item,$map_ref,$symb_ref) = @_; |
my $blocklist; |
my $blocklist; |
|
my $blockdocs; |
my ($typeorder,$types) = &blocktype_text(); |
my ($typeorder,$types) = &blocktype_text(); |
foreach my $type (@{$typeorder}) { |
foreach my $type (@{$typeorder}) { |
if ($env{'form.'.$type.'_'.$item}) { |
if ($type eq 'docs') { |
$blocklist->{$type} = 'on'; |
if ($env{'form.'.$type.'_'.$item}) { |
|
$blocklist->{$type} = {}; |
|
if ($env{'form.docs_resources_'.$item}) { |
|
$env{'form.docs_resources_'.$item} =~ s/,$//; |
|
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; |
|
} |
|
} |
|
} |
|
if ($env{'form.docs_maps_'.$item}) { |
|
$env{'form.docs_maps_'.$item} =~ s/,$//; |
|
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; |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
if ($env{'form.'.$type.'_'.$item}) { |
|
$blocklist->{$type} = 'on'; |
|
} else { |
|
$blocklist->{$type} = 'off'; |
|
} |
|
} |
|
} |
|
return ($blocklist,$blockdocs); |
|
} |
|
|
|
sub check_release_required { |
|
my ($value,$chomemajor,$chomeminor) = @_; |
|
my $needsrelease = $Apache::lonnet::needsrelease{'course:commblock:'.$value}; |
|
if ($needsrelease) { |
|
my ($needsmajor,$needsminor) = split(/\./,$needsrelease); |
|
if (($chomemajor < $needsmajor) || |
|
(($chomemajor == $needsmajor) && ($chomeminor < $needsminor))) { |
|
return ('fail',$needsrelease); |
|
} |
|
my $curr_required = |
|
$env{'course.'.$env{'request.course.id'}.'.internal.releaserequired'}; |
|
if ($curr_required eq '') { |
|
&Apache::lonnet::update_released_required($needsrelease); |
} else { |
} else { |
$blocklist->{$type} = 'off'; |
my ($currmajor,$currminor) = split(/\./,$curr_required); |
|
my ($needsmajor,$needsminor) = split(/\./,$needsrelease); |
|
if (($currmajor < $needsmajor) || |
|
($currmajor == $needsmajor && $currminor < $needsminor)) { |
|
&Apache::lonnet::update_released_required($needsrelease); |
|
} |
} |
} |
} |
} |
return $blocklist; |
return ('ok',$needsrelease); |
} |
} |
|
|
sub display_blocker_status { |
sub display_blocker_status { |
my ($r,$records,$ltext) = @_; |
my ($r,$records,$ltext,$intervals,$navmap,$errormsg,$blockcount,$readonly) = @_; |
my $parmcount = 0; |
my $parmcount = 0; |
|
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); |
my %lt = &Apache::lonlocal::texthash( |
my %lt = &Apache::lonlocal::texthash( |
'modi' => 'Modify', |
'modi' => 'Modify', |
'canc' => 'Cancel', |
'dele' => 'Delete', |
|
'noch' => 'No change', |
); |
); |
my ($typeorder,$types) = &blocktype_text(); |
$r->print('<div id="showmodify" style="display:block">'. |
$r->print(&Apache::loncommon::start_data_table()); |
&Apache::loncommon::start_data_table().'<tr>'); |
|
if ($readonly) { |
|
$disabled = ' disabled="disabled"'; |
|
} else { |
|
$r->print('<th></th>'); |
|
} |
$r->print(<<"END"); |
$r->print(<<"END"); |
<tr> |
<th>$ltext->{'type'}</th> |
<th>$ltext->{'dura'}</th> |
|
<th>$ltext->{'setb'}</th> |
|
<th>$ltext->{'even'}</th> |
<th>$ltext->{'even'}</th> |
<th>$ltext->{'blck'}</th> |
<th>$ltext->{'blck'}</th> |
<th>$ltext->{'actn'}</th> |
|
</tr> |
</tr> |
END |
END |
foreach my $record (sort(keys(%{$records}))) { |
foreach my $record (sort(keys(%{$records}))) { |
my $onchange = 'onFocus="javascript:window.document.forms['. |
my $jschg = |
"'blockform'].elements['modify_".$parmcount."'].". |
'javascript:window.document.forms['. "'blockform'".']'. |
'checked=true;"'; |
'.elements['."'action_$parmcount'".'][0].checked=true;'; |
my ($start,$end) = split(/____/,$record); |
my $onchange = 'onfocus="'.$jschg.'"'; |
my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange); |
|
my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange); |
|
|
|
my ($setuname,$setudom,$title,$blocks) = |
my ($setuname,$setudom,$title,$blocks) = |
&Apache::loncommon::parse_block_record($$records{$record}); |
&Apache::loncommon::parse_block_record($$records{$record}); |
$title = &HTML::Entities::encode($title,'"<>&'); |
$title = &HTML::Entities::encode($title,'"<>&'); |
|
my $blockid = &HTML::Entities::encode($record,'"<>&'); |
my $settername = |
my $settername = |
&Apache::loncommon::aboutmewrapper( |
&Apache::loncommon::aboutmewrapper( |
&Apache::loncommon::plainname($setuname,$setudom), |
&Apache::loncommon::plainname($setuname,$setudom), |
$setuname,$setudom); |
$setuname,$setudom); |
|
my $state = ''; |
$r->print(&Apache::loncommon::start_data_table_row()); |
$r->print(&Apache::loncommon::start_data_table_row()); |
$r->print(<<"END"); |
if ($readonly) { |
<td>$ltext->{'star'}: $startform<br />$ltext->{'endd'}: $endform</td> |
$state = 'disabled'; |
<td>$settername</td> |
} else { |
<td><input type="text" name="title_$parmcount" size="15" value="$title" /><input type="hidden" name="key_$parmcount" value="$record" /></td> |
$r->print(<<"ACT"); |
<td> |
|
END |
<td valign="middle"><span class="LC_nobreak"><label> |
foreach my $block (@{$typeorder}) { |
<input type="radio" name="action_$parmcount" value="modify" />$lt{'modi'} |
my $blockstatus = ''; |
</label></span><br /> |
if ($blocks->{$block} eq 'on') { |
<span class="LC_nobreak"><label> |
$blockstatus = 'checked="checked"'; |
<input type="radio" name="action_$parmcount" value="cancel" />$lt{'dele'} |
|
</label></span><br /> |
|
<span class="LC_nobreak"><label> |
|
<input type="radio" name="action_$parmcount" id="nochange_$parmcount" |
|
value="nochange" checked="checked" />$lt{'noch'} |
|
</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, |
|
undef,$state); |
|
$endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'. |
|
$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 $type = 'map'; |
|
my $url; |
|
if ($item eq 'course') { |
|
$type = 'course'; |
|
} elsif ($item =~ /___\d+___/) { |
|
$type = 'resource'; |
|
(my $map, my $resid, $url) = &Apache::lonnet::decode_symb($item); |
|
} else { |
|
$url = $item; |
} |
} |
$r->print('<span class="LC_nobreak"><label><input type="checkbox" name="'.$block.'_'.$parmcount.'" '.$blockstatus.' value="1" />'.$types->{$block}.'</label></span><br />'); |
$r->print('<td><fieldset><legend>'.$ltext->{'trig'}.'</legend>'); |
|
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"); |
$r->print(<<"END"); |
</td> |
<td> |
<td><span class="LC_nobreak"><label> |
<input type="text" name="title_$parmcount" size="15" value="$title" onfocus="$jschg" $disabled /> |
<input type="checkbox" name="modify_$parmcount" />$lt{'modi'} |
<input type="hidden" name="key_$parmcount" value="$blockid" /> |
</label></span><br /><span class="LC_nobreak"> |
<br /> |
<label> |
<br /> |
<input type="checkbox" name="cancel_$parmcount" />$lt{'canc'} |
$ltext->{'setb'}: $settername |
</label></span> |
</td> |
END |
END |
$r->print(&Apache::loncommon::end_data_table_row()); |
$r->print('<td>'.&blocker_checkboxes($parmcount,$blocks,$jschg,\%lookups,$disabled).'</td>'. |
|
&Apache::loncommon::end_data_table_row()); |
$parmcount++; |
$parmcount++; |
} |
} |
$r->print(<<"END"); |
$r->print(<<"END"); |
</table> |
</table> |
<br /> |
</div> |
<br /> |
|
END |
END |
return $parmcount; |
return; |
|
} |
|
|
|
sub convlim { |
|
my ($timelimit) = @_; |
|
my @order = ('days','hours','minutes','seconds'); |
|
my %catlimits = ( |
|
days => 86400, |
|
hours => 3600, |
|
minutes => 60, |
|
); |
|
my @toshow; |
|
foreach my $cat (@order) { |
|
if ($cat eq 'seconds') { |
|
if ($timelimit > 0) { |
|
push(@toshow,&mt("[_1] $cat",$timelimit)); |
|
} |
|
} elsif ($timelimit >= $catlimits{$cat}) { |
|
my $val = int($timelimit/$catlimits{$cat}); |
|
if ($val > 0) { |
|
push(@toshow,&mt("[_1] $cat",$val)); |
|
} |
|
$timelimit -= $val*$catlimits{$cat}; |
|
} |
|
} |
|
my $output = join(', ',@toshow); |
|
return $output; |
} |
} |
|
|
sub display_addblocker_table { |
sub display_addblocker_table { |
my ($r,$parmcount,$ltext) = @_; |
my ($r,$parmcount,$ltext,$intervals,$navmap,$errormsg) = @_; |
|
return unless ((ref($ltext) eq 'HASH') && (ref($intervals) eq 'HASH')); |
my $start = time; |
my $start = time; |
my $end = $start + (60 * 60 * 2); #Default is an exam of 2 hours duration. |
my $end = $start + (60 * 60 * 2); #Default is an exam of 2 hours duration. |
my $onchange = 'onFocus="javascript:window.document.forms['. |
my $onchange = 'onfocus="javascript:window.document.forms['. |
"'blockform'].elements['add_".$parmcount."'].". |
"'blockform'].elements['addaction'].". |
'checked=true;"'; |
'checked=true;"'; |
my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'.$parmcount,$start,$onchange); |
my $startform = &Apache::lonhtmlcommon::date_setter('blockform','startdate_'. |
my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'.$parmcount,$end,$onchange); |
$parmcount,$start,$onchange); |
|
my $endform = &Apache::lonhtmlcommon::date_setter('blockform','enddate_'. |
|
$parmcount,$end,$onchange); |
my %lt = &Apache::lonlocal::texthash( |
my %lt = &Apache::lonlocal::texthash( |
'addb' => 'Add block', |
|
'exam' => 'e.g., Exam 1', |
'exam' => 'e.g., Exam 1', |
'addn' => 'Add new communication blocking periods' |
|
); |
); |
my ($typeorder,$types) = &blocktype_text(); |
my $intervalform = &create_interval_form($intervals,$parmcount,$navmap,'blocking'); |
$r->print(<<"END"); |
if ($intervalform ne '') { |
<h4>$lt{'addn'}</h4> |
$intervalform = '<fieldset>'. |
END |
'<legend>'.$ltext->{'chtr'}.'</legend>'. |
|
$intervalform. |
|
'</fieldset>'; |
|
} |
$r->print(&Apache::loncommon::start_data_table()); |
$r->print(&Apache::loncommon::start_data_table()); |
$r->print(<<"END"); |
$r->print(<<"END"); |
<tr> |
<tr> |
<th>$ltext->{'dura'}</th> |
<th>$ltext->{'type'}</th> |
<th>$ltext->{'even'} $lt{'exam'}</th> |
<th>$ltext->{'even'} $lt{'exam'}</th> |
<th>$ltext->{'blck'}</th> |
<th>$ltext->{'blck'}</th> |
<th>$ltext->{'actn'}</th> |
|
</tr> |
</tr> |
END |
END |
$r->print(&Apache::loncommon::start_data_table_row()); |
$r->print(&Apache::loncommon::start_data_table_row().'<td>'); |
$r->print(<<"END"); |
$r->print(<<"END"); |
<td>$ltext->{'star'}: $startform<br />$ltext->{'endd'}: $endform</td> |
<span class="LC_nobreak"><label><input type="radio" id="toggle_startstop" |
<td><input type="text" name="title_$parmcount" size="15" value="" /></td> |
name="toggle_$parmcount" value="startstop" onclick="showBlockType();" checked="checked" /> |
<td> |
$ltext->{'defs'}</label></span> |
END |
<span class="LC_nobreak"><label><input type="radio" id="toggle_timer" name="toggle_$parmcount" |
foreach my $block (@{$typeorder}) { |
value="timer" onclick="showBlockType();" />$ltext->{'trig'}</label></span><br /> |
$r->print('<span class="LC_nobreak"><label><input type="checkbox" name="'.$block.'_'.$parmcount.'" value="1" />'.$types->{$block}.'</label></span><br />'); |
<div id="show_startstop" style="display:block"> |
} |
<fieldset><legend>$ltext->{'chda'}</legend> |
$r->print(<<"END"); |
$ltext->{'star'}: $startform<br />$ltext->{'endd'}: $endform</fieldset> |
|
<span class="LC_warning">$ltext->{'when'}</span></div> |
|
<div id="show_timer" style="display:none">$intervalform</div> |
</td> |
</td> |
<td><span class="LC_nobreak"><label> |
<td><input type="text" name="title_$parmcount" size="15" value="" /></td> |
<input type="checkbox" name="add_$parmcount" value="1" />$lt{'addb'} |
|
</label></span></td> |
|
END |
END |
$r->print(&Apache::loncommon::end_data_table_row()); |
$r->print('<td>'.&blocker_checkboxes($parmcount).'</td>'. |
$r->print(&Apache::loncommon::end_data_table()); |
&Apache::loncommon::end_data_table_row(). |
|
&Apache::loncommon::end_data_table()."\n". |
|
'<br />'); |
|
return; |
|
} |
|
|
|
sub blocker_checkboxes { |
|
my ($parmcount,$blocks,$jschg,$lookups,$disabled) = @_; |
|
my ($typeorder,$types) = &blocktype_text(); |
|
my $numinrow = 2; |
|
my %currdocs; |
|
my $output = '<table>'; |
|
for (my $i=0; $i<@{$typeorder}; $i++) { |
|
my $block = $typeorder->[$i]; |
|
my ($clickaction,$blockstatus); |
|
if ($jschg) { |
|
$clickaction = $jschg; |
|
} |
|
if ($block eq 'docs') { |
|
if ((ref($blocks) eq 'HASH') && (ref($lookups) eq 'HASH')) { |
|
if (ref($blocks->{$block}) eq 'HASH') { |
|
if (keys(%{$blocks->{$block}}) > 0) { |
|
$blockstatus = 'checked="checked"'; |
|
foreach my $key (sort(keys(%{$blocks->{$block}}))) { |
|
if (ref($blocks->{$block}{$key}) eq 'HASH') { |
|
my @current = (); |
|
foreach my $item (keys(%{$blocks->{$block}{$key}})) { |
|
if ($lookups->{$key}{$item}) { |
|
push(@current,$lookups->{$key}{$item}); |
|
} |
|
} |
|
if (@current > 0) { |
|
@current=sort { $a <=> $b } (@current); |
|
$currdocs{$key} = join(',',@current); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
$clickaction .= 'javascript:resblockinfo('."'$parmcount'".');'; |
|
} else { |
|
if (ref($blocks) eq 'HASH') { |
|
if ($blocks->{$block} eq 'on') { |
|
$blockstatus = 'checked="checked"'; |
|
} |
|
} |
|
} |
|
my $rem = $i%($numinrow); |
|
if ($rem == 0) { |
|
if ($i > 0) { |
|
$output .= '</tr>'; |
|
} |
|
$output .= '<tr>'; |
|
} |
|
if ($i == scalar(@{$typeorder})-1) { |
|
my $colsleft = $numinrow-$rem; |
|
if ($colsleft > 1) { |
|
$output .= '<td colspan="'.$colsleft.'">'; |
|
} else { |
|
$output .= '<td>'; |
|
} |
|
} else { |
|
$output .= '<td>'; |
|
} |
|
my $item = $block.'_'.$parmcount; |
|
if ($clickaction) { |
|
$clickaction = ' onclick="'.$clickaction.'"'; |
|
} |
|
if ($blockstatus) { |
|
$blockstatus = ' '.$blockstatus; |
|
} |
|
$output .= '<span class="LC_nobreak"><label>'."\n". |
|
'<input type="checkbox" id="'.$item.'" name="'.$item.'"'. |
|
$blockstatus.$clickaction.' value="1"'.$disabled.' />'. |
|
$types->{$block}.'</label></span>'."\n"; |
|
if ($block eq 'docs') { |
|
if ($blockstatus ne '') { |
|
$output .= ' <a href="javascript:resblockinfo('."'$parmcount'".')">'. |
|
&mt('Details').'</a>'; |
|
} |
|
} |
|
$output .= '<br /></td>'; |
|
} |
|
$output .= '</tr></table>'. |
|
'<input type="hidden" name="docs_maps_'.$parmcount.'"'. |
|
' id="docs_maps_'.$parmcount.'" value="'.$currdocs{'maps'}.'" />'. |
|
'<input type="hidden" name="docs_resources_'.$parmcount.'"'. |
|
' id="docs_resources_'.$parmcount.'" value="'.$currdocs{'resources'}.'" />'; |
|
return $output; |
|
} |
|
|
|
sub create_interval_form { |
|
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') { |
|
my ($checked,$clickaction); |
|
if ($currkey eq 'course') { |
|
$checked = ' checked="checked"'; |
|
} elsif ($jschg) { |
|
$clickaction = ' onclick="'.$jschg.'"'; |
|
} |
|
$intervalform .= '<label><input type="radio" name="firstaccess_'.$parmcount. |
|
'" value="course"'.$checked.$clickaction.$disabled.' />'; |
|
if ($currkey eq 'course') { |
|
$intervalform .= $itemname; |
|
} else { |
|
$intervalform .= &mt('Timer for all items in course'); |
|
} |
|
$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)) { |
|
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"'; |
|
} elsif ($jschg) { |
|
$clickaction = ' onclick="'.$jschg.'"'; |
|
} |
|
$intervalform .= '<label><input type="radio" name="firstaccess_'.$parmcount. |
|
'" value="'.&HTML::Entities::encode($map,'"<>&').'"'. |
|
$checked.$clickaction.$disabled.' />'; |
|
if ($currkey eq $map) { |
|
$intervalform .= $itemname.'</label>'.$iteminfo; |
|
} else { |
|
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). |
|
'</span>'; |
|
} |
|
$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 ++; |
|
} |
|
} |
|
} |
|
} elsif ($type eq 'resource') { |
|
if (ref($intervals->{$type}) eq 'HASH') { |
|
if (ref($navmap)) { |
|
foreach my $resource (sort(keys(%{$intervals->{$type}}))) { |
|
my ($checked,$clickaction,$resobj); |
|
if ($currkey eq $resource) { |
|
$checked = ' checked="checked"'; |
|
} 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.$disabled.' />'; |
|
if ($currkey eq $resource) { |
|
$intervalform .= $itemname.'</label>'.$iteminfo; |
|
} else { |
|
my ($title,$path,$hierarchy); |
|
if (ref($resobj)) { |
|
$title = $resobj->compTitle(); |
|
} |
|
if ($title eq '') { |
|
$title = &Apache::lonnet::gettitle($resource); |
|
} |
|
$hierarchy = &show_timer_path($type,$resource,$navmap); |
|
if ($hierarchy) { |
|
$path = ' <span style="font-size:90%;">'. |
|
&mt('(in: [_1])',$hierarchy). |
|
'</span>'; |
|
} |
|
$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 ++; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
if ($currkey ne '') { |
|
$intervalform = '<input type="radio" name="firstaccess_'.$parmcount. |
|
'" checked="checked" value="'. |
|
&HTML::Entities::encode($currkey,'"<>&').'"'.$disabled.' />'. |
|
$itemname.'<br />'; |
|
} else { |
|
$intervalform = &mt('No timed items defined.').' '. |
|
&mt('Use [_1]Settings[_2] to assign a timer, then return here.', |
|
'<a href="/adm/parmset">','</a>'); |
|
} |
|
} |
|
return $intervalform; |
|
} |
|
|
|
sub trigger_details_toggle { |
|
my ($parmcount) = @_; |
|
return ' <span id="toggletext_'.$parmcount.'" class="LC_cusr_subheading LC_nobreak">'. |
|
'<a href="javascript:showTriggerDetails('."'$parmcount'".');" '. |
|
'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)); |
|
my @pathitems; |
|
if ($type eq 'map') { |
|
@pathitems = |
|
&Apache::loncommon::get_folder_hierarchy($navmap,$item); |
|
} elsif ($type eq 'resource') { |
|
my ($map,$id,$resource) = &Apache::lonnet::decode_symb($item); |
|
@pathitems = |
|
&Apache::loncommon::get_folder_hierarchy($navmap,$map,1); |
|
} |
|
if (@pathitems) { |
|
return join(' » ',@pathitems); |
|
} |
return; |
return; |
} |
} |
|
|
Line 424 sub blocktype_text {
|
Line 1656 sub blocktype_text {
|
'port' => 'Portfolio', |
'port' => 'Portfolio', |
'groups' => 'Groups', |
'groups' => 'Groups', |
'blogs' => 'Blogs', |
'blogs' => 'Blogs', |
|
'about' => 'User Information', |
|
'docs' => 'Content', |
|
'printout' => 'Printouts', |
|
'passwd' => 'Change Password', |
|
'grades' => 'Gradebook', |
|
'search' => 'Content Search', |
|
'index' => 'Content Index', |
|
'alert' => 'Critical Alert', |
|
'reinit' => 'Course Re-init', |
); |
); |
my $typeorder = ['com','chat','boards','port','groups','blogs']; |
my $typeorder = ['com','chat','boards','port','groups','blogs','about','printout','docs','grades','search','index','alert','reinit','passwd']; |
return ($typeorder,\%types); |
return ($typeorder,\%types); |
} |
} |
|
|
|
sub blockingmenu_javascript { |
|
my ($blockcount) = @_; |
|
return <<ENDSCRIPT; |
|
<script type="text/javascript"> |
|
// <![CDATA[ |
|
function resblockinfo(blockid) { |
|
if (document.getElementById('docs_'+blockid).checked) { |
|
var resblockwin = null; |
|
var url = '/adm/setblock?action=showdocs&block='+blockid; |
|
if (!resblockwin || resblockwin.closed) { |
|
resblockwin=window.open(url,'blockingwin','height=480,width=600,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no'); |
|
} |
|
resblockwin.focus(); |
|
} else { |
|
document.getElementById('docs_resources_'+blockid).value = ''; |
|
document.getElementById('docs_maps_'+blockid).value = ''; |
|
} |
|
return; |
|
} |
|
|
|
function showBlockType() { |
|
if (document.getElementById('toggle_startstop').checked == true) { |
|
document.getElementById('show_startstop').style.display='block'; |
|
} else { |
|
document.getElementById('show_startstop').style.display='none'; |
|
} |
|
if (document.getElementById('toggle_timer').checked == true) { |
|
document.getElementById('show_timer').style.display='block'; |
|
} else { |
|
document.getElementById('show_timer').style.display='none'; |
|
} |
|
return; |
|
} |
|
|
|
function toggleAddModify() { |
|
for (var i=0; i<document.blockform.blockaction.length; i++) { |
|
if (document.blockform.blockaction[i].checked) { |
|
if (document.blockform.blockaction[i].value == 'add') { |
|
document.getElementById('showadd').style.display='block'; |
|
document.getElementById('showmodify').style.display='none'; |
|
var blocktotal = $blockcount; |
|
if (blocktotal > 0) { |
|
for (var i=0; i<blocktotal; i++) { |
|
document.getElementById('nochange_'+i).checked = true; |
|
} |
|
} |
|
document.getElementById('showmodify').style.display='none'; |
|
document.getElementById('showadd').style.display='block'; |
|
} else { |
|
document.getElementById('showadd').style.display='none'; |
|
document.getElementById('showmodify').style.display='block'; |
|
} |
|
} |
|
} |
|
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'; |
|
document.getElementById('trigdetails_'+item).style.textFace='normal'; |
|
document.getElementById('toggletext_'+item).innerHTML = '<a href="javascript:hideTriggerDetails('+item+');" style="text-decoration: none;"><b>($lt{'less'})</b></a>'; |
|
return; |
|
} |
|
|
|
function hideTriggerDetails(item) { |
|
document.getElementById('trigdetails_'+item).style.display='none'; |
|
document.getElementById('toggletext_'+item).innerHTML = '<a href="javascript:showTriggerDetails('+item+');" style="text-decoration: none;"><b>($lt{'more'})</b></a>'; |
|
return; |
|
} |
|
|
|
// ]]> |
|
</script> |
|
ENDSCRIPT |
|
|
|
} |
|
|
1; |
1; |
|
|
__END__ |
__END__ |