Annotation of loncom/interface/lonrequestcourse.pm, revision 1.2
1.1 raeburn 1: # The LearningOnline Network
2: # Request a course
3: #
1.2 ! raeburn 4: # $Id: lonrequestcourse.pm,v 1.1 2009/07/27 22:58:24 raeburn Exp $
1.1 raeburn 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28: ###
29:
30: =head1 NAME
31:
32: Apache::lonrequestcourse.pm
33:
34: =head1 SYNOPSIS
35:
36: Allows users to request creation of new courses.
37:
38: This is part of the LearningOnline Network with CAPA project
39: described at http://www.lon-capa.org.
40:
41: =head1 SUBROUTINES
42:
43: =over
44:
45: =item handler()
46:
47: =back
48:
49: =cut
50:
51: package Apache::lonrequestcourse;
52:
53: use strict;
54: use Apache::Constants qw(:common :http);
55: use Apache::lonnet;
56: use Apache::loncommon;
57: use Apache::lonlocal;
58: use LONCAPA;
59:
60: sub handler {
61: my ($r) = @_;
62: if ($r->header_only) {
63: &Apache::loncommon::content_type($r,'text/html');
64: $r->send_http_header;
65: return OK;
66: }
67: &Apache::loncommon::content_type($r,'text/html');
68: $r->send_http_header;
69:
1.2 ! raeburn 70: &Apache::lonhtmlcommon::clear_breadcrumbs();
! 71: my $dom = &get_course_dom();
1.1 raeburn 72: my $action = $env{'form.action'};
73: my $state = $env{'form.state'};
1.2 ! raeburn 74:
! 75: my %stored;
! 76: my $jscript;
! 77: if ((defined($state)) && (defined($action))) {
! 78: my %elements = &form_elements($dom);
! 79: if (($action eq 'view') && ($state ne 'crstype')) {
! 80: if (defined($env{'form.request_id'})) {
! 81: %stored = &retrieve_settings($dom,$env{'form.request_id'});
! 82: }
! 83: }
! 84: my $elementsref = {};
! 85: if (ref($elements{$action}) eq 'HASH') {
! 86: if (ref($elements{$action}{$state}) eq 'HASH') {
! 87: $elementsref = $elements{$action}{$state};
! 88: }
! 89: }
! 90: $jscript = &Apache::lonhtmlcommon::set_form_elements($elementsref,\%stored);
! 91: }
! 92:
! 93: if ($state eq 'personnel') {
! 94: $jscript .= "\n".&Apache::loncommon::userbrowser_javascript();
! 95: }
! 96:
! 97: my $loaditems = &onload_action($action,$state);
! 98:
! 99: my %states;
! 100: $states{'view'} = ['pick_request','details','review','process'];
! 101: $states{'log'} = ['filter','display'];
! 102: $states{'new'} = ['courseinfo','enrollment','personnel','review','process'];
! 103: if (($action eq 'new') && ($env{'form.crstype'} eq 'official')) {
! 104: unless ($env{'form.state'} eq 'crstype') {
! 105: unshift (@{$states{'new'}},'codepick');
! 106: }
! 107: }
! 108:
! 109: foreach my $key (keys(%states)) {
! 110: if (ref($states{$key}) eq 'ARRAY') {
! 111: unshift (@{$states{$key}},'crstype');
! 112: }
! 113: }
! 114:
! 115: my $page = 0;
! 116: if (defined($action)) {
! 117: my $done = 0;
! 118: my $i=0;
! 119: if (ref($states{$action}) eq 'ARRAY') {
! 120: while ($i<@{$states{$action}} && !$done) {
! 121: if ($states{$action}[$i] eq $state) {
! 122: $page = $i;
! 123: $done = 1;
! 124: }
! 125: $i++;
! 126: }
! 127: }
! 128: }
! 129:
1.1 raeburn 130: my %can_request;
131: my $canreq = &check_can_request($dom,\%can_request);
132: if ($action eq 'new') {
133: if ($canreq) {
134: if ($state eq 'crstype') {
1.2 ! raeburn 135: &print_main_menu($r,\%can_request,\%states,$dom,$jscript,$loaditems);
1.1 raeburn 136: } else {
1.2 ! raeburn 137: &request_administration($r,$action,$state,$page,\%states,$dom,$jscript,
! 138: $loaditems);
1.1 raeburn 139: }
140: } else {
1.2 ! raeburn 141: $r->print(&header('Course Requests').
1.1 raeburn 142: '<div class="LC_warning">'.
143: &mt('You do not have privileges to request creation of courses.').
1.2 ! raeburn 144: '</div>'.&Apache::loncommon::end_page());
1.1 raeburn 145: }
146: } elsif ($action eq 'view') {
1.2 ! raeburn 147: &print_request_status($jscript,$loaditems);
1.1 raeburn 148: } elsif ($action eq 'log') {
1.2 ! raeburn 149: &print_request_logs($jscript,$loaditems);
1.1 raeburn 150: } else {
1.2 ! raeburn 151: &print_main_menu($r,\%can_request,\%states,$dom,$jscript);
1.1 raeburn 152: }
153: return OK;
154: }
155:
1.2 ! raeburn 156: sub header {
! 157: my ($bodytitle,$jscript,$loaditems,$jsextra) = @_;
! 158: if ($jscript) {
! 159: $jscript = '<script type="text/javascript">'.
! 160: $jscript.'</script>'."\n";
! 161: }
! 162: if ($loaditems) {
! 163: $loaditems = {'add_entries' => $loaditems,};
! 164: }
! 165: return &Apache::loncommon::start_page($bodytitle,$jscript.$jsextra,$loaditems);
! 166: }
! 167:
! 168: sub form_elements {
! 169: my ($dom) = @_;
! 170: my %elements =
! 171: (
! 172: new => {
! 173: crstype => {
! 174: crstype => 'selectbox',
! 175: action => 'selectbox',
! 176: },
! 177: courseinfo => {
! 178: cdescr => 'text',
! 179: clonecourse => 'text',
! 180: clonedomain => 'selectbox',
! 181: datemode => 'radio',
! 182: dateshift => 'text',
! 183: },
! 184: enrollment => {
! 185: startaccess_month => 'selectbox',
! 186: startaccess_hour => 'selectbox',
! 187: endaccess_month => 'selectbox',
! 188: endaccess_hour => 'selectbox',
! 189: startaccess_day => 'text',
! 190: startaccess_year => 'text',
! 191: startaccess_minute => 'text',
! 192: startaccess_second => 'text',
! 193: endaccess_day => 'text',
! 194: endaccess_year => 'text',
! 195: endaccess_minute => 'text',
! 196: endaccess_second => 'text',
! 197: no_end_date => 'checkbox',
! 198: },
! 199: personnel => {
! 200: persontotal => 'hidden',
! 201: addperson => 'checkbox',
! 202: },
! 203: },
! 204: view => {
! 205: crstype => {
! 206: crstype => 'selectbox',
! 207: action => 'selectbox',
! 208: },
! 209: },
! 210: );
! 211: my (@codetitles,%cat_titles,%cat_order,@code_order,$lastitem);
! 212: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
! 213: \%cat_order,\@code_order);
! 214: my $numtitles = scalar(@codetitles);
! 215: if ($numtitles) {
! 216: my %extras;
! 217: $lastitem = pop(@codetitles);
! 218: $extras{'instcode_'.$lastitem} = 'text';
! 219: foreach my $item (@codetitles) {
! 220: $extras{'instcode_'.$item} = 'selectbox';
! 221: }
! 222: $elements{'new'}{'codepick'} = \%extras;
! 223: }
! 224: if (&Apache::lonnet::auto_run('',$dom)) {
! 225: my %extras = (
! 226: sectotal => 'hidden',
! 227: startenroll_month => 'selectbox',
! 228: startenroll_hour => 'selectbox',
! 229: endenroll_month => 'selectbox',
! 230: endenroll_hour => 'selectbox',
! 231: startenroll_day => 'text',
! 232: startenroll_year => 'text',
! 233: startenroll_minute => 'text',
! 234: startenroll_second => 'text',
! 235: endenroll_day => 'text',
! 236: endenroll_year => 'text',
! 237: endenroll_minute => 'text',
! 238: endenroll_second => 'text',
! 239: crosslisttotal => 'hidden',
! 240: addcrosslist => 'checkbox',
! 241: autoadds => 'radio',
! 242: autodrops => 'radio',
! 243: );
! 244: if ($env{'form.sectotal'} > 0) {
! 245: for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
! 246: $extras{'sec_'.$i} = 'checkbox',
! 247: $extras{'secnum_'.$i} = 'text',
! 248: $extras{'loncapasec_'.$i} = 'checkbox',
! 249: }
! 250: }
! 251: my $crosslisttotal = $env{'form.crosslisttotal'};
! 252: if (!defined($crosslisttotal)) {
! 253: $crosslisttotal = 1;
! 254: }
! 255: if ($crosslisttotal > 0) {
! 256: for (my $i=0; $i<$env{'form.crosslisttotal'}; $i++) {
! 257: if ($numtitles) {
! 258: $extras{'crosslist_'.$i.'_'.$lastitem} = 'text';
! 259: }
! 260: if (@codetitles > 0) {
! 261: foreach my $item (@codetitles) {
! 262: $extras{'crosslist_'.$i.'_'.$item} = 'selectbox';
! 263: }
! 264: }
! 265: $extras{'crosslist_'.$i} = 'checkbox';
! 266: $extras{'crosslist_'.$i.'_instsec'} = 'text',
! 267: $extras{'crosslist_'.$i.'_lcsec'} = 'text',
! 268: }
! 269: }
! 270: my %mergedhash = (%{$elements{'new'}{'enrollment'}},%extras);
! 271: %{$elements{'new'}{'enrollment'}} = %mergedhash;
! 272: }
! 273: my %people;
! 274: my $persontotal = $env{'form.persontotal'};
! 275: if (!defined($persontotal)) {
! 276: $persontotal = 1;
! 277: }
! 278: for (my $i=0; $i<$persontotal; $i++) {
! 279: $people{'person_'.$i.'_uname'} = 'text',
! 280: $people{'person_'.$i.'_dom'} = 'selectbox',
! 281: $people{'person_'.$i.'_hidedom'} = 'hidden',
! 282: $people{'person_'.$i.'_first'} = 'text',
! 283: $people{'person_'.$i.'_last'} = 'text',
! 284: $people{'person_'.$i.'_email'} = 'text',
! 285: $people{'person_'.$i.'_role'} = 'selectbox',
! 286: $people{'person_'.$i.'_sec'} = 'selectbox',
! 287: $people{'person_'.$i.'_newsec'} = 'text',
! 288: $people{'person_'.$i.'_sections'} = 'hidden',
! 289: }
! 290: my %personnelhash = (%{$elements{'new'}{'personnel'}},%people);
! 291: %{$elements{'new'}{'personnel'}} = %personnelhash;
! 292: return %elements;
! 293: }
! 294:
! 295: sub onload_action {
! 296: my ($action,$state) = @_;
! 297: my %loaditems;
! 298: if (($action eq 'new') || ($action eq 'view')) {
! 299: $loaditems{'onload'} = 'javascript:setFormElements(document.requestcrs)';
! 300: }
! 301: return \%loaditems;
! 302: }
! 303:
1.1 raeburn 304: sub check_can_request {
305: my ($dom,$can_request) = @_;
306: my $canreq = 0;
307: if (ref($can_request) eq 'HASH') {
308: foreach my $type ('official','unofficial','community') {
309: if (&Apache::lonnet::usertools_access($env{'user.name'},
310: $env{'user.domain'},
311: $type,undef,'requestcourses')) {
312: $canreq ++;
313: if ($dom eq $env{'user.domain'}) {
314: $can_request->{$type} = 1;
315: }
316: }
317: if ($env{'environment.reqcrsotherdom.'.$type} ne '') {
318: my @curr = split(',',$env{'environment.reqcrsotherdom.'.$type});
319: if (@curr > 0) {
320: $canreq ++;
321: unless ($dom eq $env{'user.domain'}) {
322: if (grep(/^\Q$dom\E$/,@curr)) {
323: $can_request->{$type} = 1;
324: }
325: }
326: }
327: }
328: }
329: }
330: return $canreq;
331: }
332:
333: sub print_main_menu {
1.2 ! raeburn 334: my ($r,$can_request,$states,$dom,$jscript,$loaditems) = @_;
1.1 raeburn 335: my $onchange;
336: unless ($env{'form.interface'} eq 'textual') {
337: $onchange = 1;
338: }
339:
1.2 ! raeburn 340: my $nextstate_setter = "\n";
! 341: if (ref($states) eq 'HASH') {
! 342: foreach my $key (keys(%{$states})) {
! 343: if (ref($states->{$key}) eq 'ARRAY') {
! 344: $nextstate_setter .=
! 345: " if (actionchoice == '$key') {
! 346: nextstate = '".$states->{$key}[1]."';
! 347: }
! 348: ";
! 349: }
! 350: }
! 351: }
1.1 raeburn 352:
1.2 ! raeburn 353: my $js = <<"END";
1.1 raeburn 354:
1.2 ! raeburn 355: function nextPage(formname) {
! 356: var crschoice = document.requestcrs.crstype.value;
! 357: var actionchoice = document.requestcrs.action.value;
! 358: if (check_can_request(crschoice,actionchoice) == true) {
! 359: if ((actionchoice == 'new') && (crschoice == 'official')) {
! 360: nextstate = 'codepick';
! 361: } else {
! 362: $nextstate_setter
! 363: }
1.1 raeburn 364: formname.state.value= nextstate;
365: formname.submit();
366: }
367: return;
368: }
369:
1.2 ! raeburn 370: function check_can_request(crschoice,actionchoice) {
1.1 raeburn 371: var official = '';
372: var unofficial = '';
373: var community = '';
374: END
375:
376: foreach my $item (keys(%{$can_request})) {
377: $js .= "
378: $item = 1;
379: ";
380: }
381: my %lt = &Apache::lonlocal::texthash(
382: official => 'You are not permitted to request creation of an official course in this domain.',
383: unofficial => 'You are not permitted to request creation of an unofficial course in this domain.',
384: community => 'You are not permitted to request creation of a community this domain.',
385: all => 'You must choose a specific course type when making a new course request.\\nAll types is not allowed.',
386: );
387: $js .= <<END;
388: if (crschoice == 'official') {
389: if (official != 1) {
390: alert("$lt{'official'}");
391: return false;
392: }
393: } else {
394: if (crschoice == 'unofficial') {
395: if (unofficial != 1) {
396: alert("$lt{'unofficial'}");
397: return false;
398: }
399: } else {
400: if (crschoice == 'community') {
401: if (community != 1) {
402: alert("$lt{'community'}");
403: return false;
404: }
405: } else {
406: if (actionchoice == 'new') {
407: alert("$lt{'all'}");
408: return false;
409: }
410: }
411: }
412: }
413: return true;
414: }
415:
416: END
417:
1.2 ! raeburn 418: $r->print(&header('Course Requests',$js.$jscript,$loaditems).
1.1 raeburn 419: '<p><div>'.
420: '<form name="domforcourse" method="post" action="/adm/requestcourse">'.
421: &Apache::lonhtmlcommon::start_pick_box().
422: &Apache::lonhtmlcommon::row_title('Domain').
423: &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange));
424: if (!$onchange) {
425: $r->print(' <input type="submit" name="godom" value="'.
426: &mt('Change').'" />');
427: }
428: $r->print(&Apache::lonhtmlcommon::row_closure(1).
429: &Apache::lonhtmlcommon::end_pick_box().'</form></div>');
430:
1.2 ! raeburn 431: my $formname = 'requestcrs';
1.1 raeburn 432: my $nexttext = &mt('Next');
433: $r->print('<div><form name="'.$formname.'" method="post" action="/adm/requestcourse">'.
434: &Apache::lonhtmlcommon::start_pick_box().
435: &Apache::lonhtmlcommon::row_title('Action').'
436: <input type="hidden" name="showdom" value="'.$dom.'" />
437: <select size="1" name="action" >
1.2 ! raeburn 438: <option value="new">'.&mt('New request').'</option>
1.1 raeburn 439: <option value="view">'.&mt('View/Modify/Cancel pending requests').'</option>
440: <option value="log">'.&mt('View request history').'</option>
441: </select>'.
442: &Apache::lonhtmlcommon::row_closure().
443: &Apache::lonhtmlcommon::row_title('Course Type').'
444: <select size="1" name="crstype">
445: <option value="any">'.&mt('All types').'</option>
1.2 ! raeburn 446: <option value="official" selected="selected">'.&mt('Official course').'</option>
1.1 raeburn 447: <option value="unofficial">'.&mt('Unofficial course').'</option>
448: <option value="community">'.&mt('Community').'</option>
449: </select>
450: <input type="hidden" name="state" value="crstype" />'.
451: &Apache::lonhtmlcommon::row_closure(1).
452: &Apache::lonhtmlcommon::end_pick_box().'<br />
1.2 ! raeburn 453: <input type="button" name="next" value="'.$nexttext.'" onclick="javascript:nextPage(document.'.$formname.')" />
1.1 raeburn 454: </form></div>');
455: $r->print(&Apache::loncommon::end_page());
456: return;
457: }
458:
459: sub request_administration {
1.2 ! raeburn 460: my ($r,$action,$state,$page,$states,$dom,$jscript,$loaditems) = @_;
! 461: my $js;
! 462: if (($action eq 'new') || ($action eq 'view')) {
! 463: $js = <<END;
1.1 raeburn 464:
465: function nextPage(formname,nextstate) {
466: formname.state.value= nextstate;
467: formname.submit();
468: }
469: function backPage(formname,prevstate) {
470: formname.state.value = prevstate;
471: formname.submit();
472: }
473:
474: END
1.2 ! raeburn 475: }
! 476: if ($action eq 'new') {
! 477: my $jsextra;
1.1 raeburn 478: unless (($state eq 'review') || ($state eq 'process')) {
1.2 ! raeburn 479: $jsextra = "\n".&Apache::loncommon::coursebrowser_javascript($dom);
1.1 raeburn 480: }
1.2 ! raeburn 481: $r->print(&header('Request a course',$js.$jscript,$loaditems,$jsextra));
1.1 raeburn 482: if ($state eq 'review') {
483: &print_review($r,$state,$dom);
484: } elsif ($state eq 'process') {
485: &print_request_outcome($r,$state,$dom);
486: } else {
1.2 ! raeburn 487: &print_request_form($r,$action,$state,$page,$states,$dom);
1.1 raeburn 488: }
1.2 ! raeburn 489: } elsif ($action eq 'view') {
! 490: $r->print(&header('Manage course requests',$js.$jscript,$loaditems));
1.1 raeburn 491: } elsif ($action eq 'log') {
1.2 ! raeburn 492: $r->print(&coursereq_log('View request log',$jscript,$loaditems));
1.1 raeburn 493: }
1.2 ! raeburn 494: $r->print(&Apache::loncommon::end_page());
1.1 raeburn 495: return;
496: }
497:
498: sub print_request_form {
1.2 ! raeburn 499: my ($r,$action,$state,$page,$states,$dom) = @_;
1.1 raeburn 500: my $formname = 'requestcrs';
1.2 ! raeburn 501: my ($next,$prev,$message,$output,$codepicker,$crstype);
! 502: $prev = $states->{$action}[$page-1];
! 503: $next = $states->{$action}[$page+1];
! 504: $crstype = $env{'form.crstype'};
1.1 raeburn 505: $r->print('<form name="'.$formname.'" method="post" action="/adm/requestcourse">');
1.2 ! raeburn 506: my (@codetitles,%cat_titles,%cat_order,@code_order,$instcode,$code_chk);
1.1 raeburn 507: if ($crstype eq 'official') {
508: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
509: \%cat_order,\@code_order);
1.2 ! raeburn 510: if ($env{'form.instcode'} ne '') {
! 511: $instcode = $env{'form.instcode'};
! 512: }
! 513: }
! 514: if ($prev eq 'codepick') {
! 515: if (@code_order > 0) {
! 516: my $message;
! 517: if ($instcode eq '') {
1.1 raeburn 518: foreach my $item (@code_order) {
1.2 ! raeburn 519: $instcode .= $env{'form.instcode_'.$item};
1.1 raeburn 520: }
1.2 ! raeburn 521: $r->print('<input type="hidden" name="instcode" value="'.$instcode.'" />'."\n");
1.1 raeburn 522: }
523: if ($instcode ne '') {
1.2 ! raeburn 524: $code_chk = &Apache::lonnet::auto_validate_instcode('',$dom,$instcode);
1.1 raeburn 525: if ($code_chk eq 'ok') {
526: $message = '<div class="LC_info">'.
527: &mt('The chosen course category [_1] is valid.','<b>'.
1.2 ! raeburn 528: $instcode.'</b>').'</div>';
1.1 raeburn 529: } else {
530: $message = '<div class="LC_warning">'.
531: &mt('No course was found matching your choice of institutional course category.');
532: if ($code_chk ne '') {
533: $message .= '<br />'.$code_chk;
534: }
535: $message .= '</div>';
536: }
1.2 ! raeburn 537: } else {
! 538: $message = '<div class="LC_warning">'.
! 539: &mt('No course was found matching your choice of institutional course category.');
1.1 raeburn 540: }
1.2 ! raeburn 541: unless ($code_chk eq 'ok') {
! 542: $prev = 'crstype';
! 543: }
! 544: $r->print($message);
1.1 raeburn 545: }
1.2 ! raeburn 546: }
! 547: if ($prev eq 'crstype') {
! 548: if (@code_order > 0) {
1.1 raeburn 549: $codepicker = &coursecode_form($dom,'instcode',\@codetitles,
550: \%cat_titles,\%cat_order);
1.2 ! raeburn 551: if ($codepicker) {
! 552: $r->print('<div>'.&Apache::lonhtmlcommon::start_pick_box().$codepicker.
! 553: &Apache::lonhtmlcommon::end_pick_box().'</div>');
! 554: } else {
! 555: $r->print(&courseinfo_form($dom,$formname,$crstype));
! 556: }
! 557: } else {
! 558: $r->print(&courseinfo_form($dom,$formname,$crstype));
1.1 raeburn 559: }
1.2 ! raeburn 560: } elsif ($prev eq 'codepick') {
! 561: $r->print(&courseinfo_form($dom,$formname,$crstype));
! 562: } elsif ($state eq 'enrollment') {
! 563: $r->print(&print_enrollment_menu($formname,$instcode,$dom,\@codetitles,
! 564: \%cat_titles,\%cat_order,\@code_order));
! 565: } elsif ($state eq 'personnel') {
! 566: $r->print(&print_personnel_menu($dom,$formname));
1.1 raeburn 567: }
1.2 ! raeburn 568: my @excluded = ('counter');
! 569: my %elements = &form_elements($dom);
! 570: if (ref($states) eq 'HASH') {
! 571: if (ref($states->{$action}) eq 'ARRAY') {
! 572: my @items = @{$states->{$action}};
! 573: my $numitems = scalar(@items);
! 574: if ($numitems) {
! 575: for (my $i=$numitems-1; $i>=0; $i--) {
! 576: if (ref($elements{$action}) eq 'HASH') {
! 577: if (ref($elements{$action}{$items[$i]}) eq 'HASH') {
! 578: foreach my $key (keys(%{$elements{$action}{$items[$i]}})) {
! 579: push(@excluded,$key);
! 580: }
! 581: }
! 582: }
! 583: last if ($items[$i] eq $state);
! 584: }
! 585: }
! 586: }
! 587: }
! 588: if (grep(/^instcode_/,@excluded)) {
! 589: push(@excluded,'instcode');
1.1 raeburn 590: }
1.2 ! raeburn 591: $r->print(&Apache::lonhtmlcommon::echo_form_input(\@excluded).'</form>');
1.1 raeburn 592: &display_navbuttons($r,$formname,$prev,'Previous',$next,'Next');
593: return;
594: }
595:
1.2 ! raeburn 596: sub print_enrollment_menu {
! 597: my ($formname,$instcode,$dom,$codetitles,$cat_titles,$cat_order,$code_order) =@_;
! 598: my ($sections,$autoenroll,$access_dates);
! 599: my $starttime = time;
! 600: my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
! 601:
! 602: my %accesstitles = (
! 603: 'start' => 'Default start access',
! 604: 'end' => 'Default end accss',
! 605: );
! 606: my %enrolltitles = (
! 607: 'start' => 'Start auto-enrollment',
! 608: 'end' => 'End auto-enrollment',
! 609: );
! 610: if ($env{'form.crstype'} eq 'official') {
! 611: if (&Apache::lonnet::auto_run('',$dom)) {
! 612: my ($section_form,$crosslist_form,$autoenroll_form);
! 613: $section_form = &inst_section_selector($dom,$instcode);
! 614: my $crosslisttotal = $env{'form.crosslisttotal'};
! 615: if (!defined($crosslisttotal)) {
! 616: $crosslisttotal = 1;
! 617: }
! 618: if ($env{'form.addcrosslist'}) {
! 619: $crosslisttotal ++;
! 620: }
! 621: for (my $i=0; $i<$crosslisttotal; $i++) {
! 622: $crosslist_form .= &coursecode_form($dom,'crosslist',$codetitles,
! 623: $cat_titles,$cat_order,$i);
! 624: }
! 625: if ($crosslist_form) {
! 626: $crosslist_form .=
! 627: &Apache::lonhtmlcommon::row_title(&mt('Add another?')).
! 628: '<input name="crosslisttotal" type="hidden" value="'.$crosslisttotal.'" />'.
! 629: '<input name="addcrosslist" type="checkbox" value="'.$crosslisttotal.'"'.
! 630: ' onclick="javascript:nextPage(document.'.$formname.",'".$env{'form.state'}.
! 631: "'".');" />'.&mt('Add?').&Apache::lonhtmlcommon::row_closure(1);
! 632: }
! 633: if ($section_form || $crosslist_form) {
! 634: $sections = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
! 635: $section_form.$crosslist_form.
! 636: &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n";
! 637: }
! 638: $autoenroll_form =
! 639: &Apache::lonhtmlcommon::row_title(&mt('Add registered students automatically')).
! 640: '<span class="LC_nobreak"><label>'.
! 641: '<input type="radio" name="autoadds" value="1">'.
! 642: &mt('Yes').'</label>'.(' 'x3).'<label>'.
! 643: '<input type="radio" name="autoadds" value="0" checked="checked">'.
! 644: &mt('No').'</label></span>'.
! 645: &Apache::lonhtmlcommon::row_closure().
! 646: &Apache::lonhtmlcommon::row_title(&mt('Drop unregistered students automatically')).
! 647: '<span class="LC_nobreak"><label>'.
! 648: '<input type="radio" name="autodrops" value="1">'.
! 649: &mt('Yes').'</label>'.(' 'x3).'<label>'.
! 650: '<input type="radio" name="autodrops" value="0" checked="checked">'.
! 651: &mt('No').'</label></span>'.
! 652: &Apache::lonhtmlcommon::row_closure().
! 653: &date_setting_table($starttime,$endtime,$formname,'enroll',%enrolltitles);
! 654: if ($autoenroll_form) {
! 655: $autoenroll = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
! 656: $autoenroll_form.
! 657: &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n";
! 658: }
! 659: }
! 660: }
! 661: my $access_dates_form =
! 662: &date_setting_table($starttime,$endtime,$formname,'access',%accesstitles);
! 663: if ($access_dates_form) {
! 664: $access_dates = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
! 665: $access_dates_form.
! 666: &Apache::lonhtmlcommon::end_pick_box().'</div>'."\n";
! 667: }
! 668: return $sections.$autoenroll.$access_dates;
! 669: }
! 670:
1.1 raeburn 671: sub inst_section_selector {
1.2 ! raeburn 672: my ($dom,$instcode) = @_;
! 673: my @sections = &Apache::lonnet::auto_get_sections(undef,$dom,$instcode);
! 674: my $sectotal = scalar(@sections);
1.1 raeburn 675: my $output;
1.2 ! raeburn 676: if ($sectotal) {
! 677: $output .= &Apache::lonhtmlcommon::row_title('Sections').
! 678: &Apache::loncommon::start_data_table().
! 679: &Apache::loncommon::start_data_table_row().
! 680: '<th>'.&mt('Include?').'<input type="hidden" name="sectotal" '.
! 681: 'value="'.$sectotal.'"</th>'.
! 682: '<th>'.&mt('Institutional Section').'</th>'.
! 683: '<th>'.&mt('LON-CAPA section').'</th>'.
! 684: &Apache::loncommon::end_data_table_row();
! 685: for (my $i=0; $i<@sections; $i++) {
1.1 raeburn 686: my $colflag = $i%2;
687: $output .= &Apache::loncommon::start_data_table_row().
1.2 ! raeburn 688: '<td><input type="checkbox" name="sec_'.$i.
! 689: '" checked="checked" /></td>'.
! 690: '<td>'.$sections[$i].
1.1 raeburn 691: '<input type="hidden" name="secnum_'.$i.'" value="'.
1.2 ! raeburn 692: $sections[$i].'" /></td>'.
1.1 raeburn 693: '<td><input type="text" size="10" name="loncapasec_'.$i.
1.2 ! raeburn 694: '" value="'.$sections[$i].'" /></td>'.
1.1 raeburn 695: &Apache::loncommon::end_data_table_row();
696: }
1.2 ! raeburn 697: $output .= &Apache::loncommon::end_data_table().
! 698: &Apache::lonhtmlcommon::row_closure();
1.1 raeburn 699: }
700: return $output;
701: }
702:
1.2 ! raeburn 703: sub date_setting_table {
! 704: my ($starttime,$endtime,$formname,$suffix,%datetitles) = @_;
! 705: my ($perpetual,$table);
! 706: my $startform = &Apache::lonhtmlcommon::date_setter($formname,'start'.$suffix,
! 707: $starttime,'','','',1,'','','',1);
! 708: my $endform = &Apache::lonhtmlcommon::date_setter($formname,'end'.$suffix,
! 709: $endtime,'','','',1,'','','',1);
! 710: if ($suffix eq 'access') {
! 711: $perpetual = ' <span class="LC_nobreak"><label>'.
! 712: '<input type="checkbox" name="no_end_date" />'.
! 713: &mt('No end date').'</label></span>';
! 714: }
! 715: $table = &Apache::lonhtmlcommon::row_title($datetitles{'start'}).
! 716: $startform.
! 717: &Apache::lonhtmlcommon::row_closure().
! 718: &Apache::lonhtmlcommon::row_title($datetitles{'end'}).
! 719: $endform.$perpetual.
! 720: &Apache::lonhtmlcommon::row_closure(1);
! 721: return $table;
! 722: }
! 723:
! 724: sub print_personnel_menu {
! 725: my ($dom,$formname) = @_;
! 726: my $output = '<div>'.&Apache::lonhtmlcommon::start_pick_box();
! 727: my $persontotal = $env{'form.persontotal'};
! 728: if (!defined($persontotal)) {
! 729: $persontotal = 1;
! 730: }
! 731: if ($env{'form.addperson'}) {
! 732: $persontotal ++;
! 733: }
! 734: my $userlinktxt = &mt('Set User');
! 735: my @items = ('uname','dom','last','first','email','hidedom');
! 736:
! 737: my $roleoptions;
! 738: my @roles = &Apache::lonuserutils::roles_by_context('course');
! 739: foreach my $role (@roles) {
! 740: my $plrole=&Apache::lonnet::plaintext($role);
! 741: $roleoptions .= ' <option value="'.$role.'">'.$plrole.'</option>'."\n";
! 742: }
! 743: my %customroles=&Apache::lonuserutils::my_custom_roles();
! 744: if (keys(%customroles) > 0) {
! 745: foreach my $cust (sort(keys(%customroles))) {
! 746: my $custrole='cr_cr_'.$env{'user.domain'}.
! 747: '_'.$env{'user.name'}.'_'.$cust;
! 748: $roleoptions .= ' <option value="'.$custrole.'">'.$cust.'</option>'."\n";
! 749: }
! 750: }
! 751:
! 752: my @currsecs;
! 753: if ($env{'form.sectotal'}) {
! 754: for (my $i=0; $i<$env{'form.sectotal'}; $i++) {
! 755: if (defined($env{'form.loncapasec_'.$i})) {
! 756: my $lcsec = $env{'form.loncapasec_'.$i};
! 757: unless (grep(/^\Q$lcsec\E$/,@currsecs)) {
! 758: push(@currsecs,$lcsec);
! 759: }
! 760: }
! 761: }
! 762: }
! 763:
! 764: my ($existtitle,$existops,$existmult,$newtitle,$seccolspan);
! 765: if (@currsecs) {
! 766: my $existsize = scalar(@currsecs);
! 767: if ($existsize > 3) {
! 768: $existsize = 3;
! 769: }
! 770: if ($existsize > 1) {
! 771: $existmult = ' multiple="multiple" size="'.$existsize.'" ';
! 772: }
! 773: @currsecs = sort { $a <=> $b } (@currsecs);
! 774: $existtitle = &mt('Official').': ';
! 775: $existops = '<option value="">'.&mt('None').'</option>';
! 776: foreach my $sec (@currsecs) {
! 777: $existops .= '<option value="'.$sec.'">'.$sec.'</option>'."\n";
! 778: }
! 779: $seccolspan = ' colspan="2"';
! 780: $newtitle = &mt('Other').': ';
! 781: }
! 782:
! 783: for (my $i=0; $i<$persontotal; $i++) {
! 784: my @linkargs = map { 'person_'.$i.'_'.$_ } (@items);
! 785: my $linkargstr = join("','",@linkargs);
! 786: my $userlink = &Apache::loncommon::selectuser_link($formname,@linkargs,$userlinktxt);
! 787: my $uname_form = '<input type="text" name="person_'.$i.'_uname" value=""'.
! 788: ' onFocus="this.blur();'.
! 789: 'openuserbrowser('."'$formname','$linkargstr'".');" />';
! 790: my $onchange = 'javascript:fix_domain('."'$formname','person_".$i."_dom',".
! 791: "'person_".$i."_hidedom'".');'.
! 792: 'openuserbrowser('."'$formname','$linkargstr'".');';
! 793: my $udom_form = &Apache::loncommon::select_dom_form($dom,'person_'.$i.'_dom','',
! 794: 1,$onchange).
! 795: '<input type="hidden" name="person_'.$i.'_hidedom" value="'.$dom.'" />';
! 796: my %form_elems;
! 797: foreach my $item (@items) {
! 798: next if (($item eq 'dom') || ($item eq 'uname') || ($item eq 'hidedom'));
! 799: $form_elems{$item} = '<input type="text" name="person_'.$i.'_'.$item.'" '.
! 800: 'value="" readonly="readonly" />';
! 801: }
! 802: my $roleselector = '<select name="person_'.$i.'_role">'."\n".
! 803: $roleoptions.'</select>';
! 804: my $sectionselector;
! 805: if (@currsecs) {
! 806: $sectionselector = $existtitle.'<select name="person_'.$i.'_sec"'.
! 807: $existmult.'>'."\n".$existops.'</select>'.(' ' x3);
! 808: }
! 809: $sectionselector .= $newtitle.
! 810: '<input type="text" name="person_'.$i.'_newsec" size="15" value="" />'.
! 811: '<input type="hidden" name="person_'.$i.'_sections" value="" />'."\n";
! 812:
! 813: $output .=
! 814: &Apache::lonhtmlcommon::row_title(&mt('Additional Personnel').'<br />'.
! 815: '<span class="LC_nobreak">'.$userlink.
! 816: '</span>').
! 817: '<table><tr><td align="center" valign="top">'.&mt('Username').'<br />'.$uname_form.'</td>'."\n".
! 818: '<td align="center" valign="top" colspan="2">'.&mt('Domain').'<br />'.$udom_form.'</td></tr><tr>'."\n".
! 819: '<td align="center" valign="top">'.&mt('First Name').'<br />'.$form_elems{'first'}.'</td>'."\n".
! 820: '<td align="center" valign="top">'.&mt('Last Name').'<br />'.$form_elems{'last'}.'</td>'."\n".
! 821: '<td align="center" valign="top">'.&mt('E-mail').'<br />'.$form_elems{email}.'</td></tr>'."\n".
! 822: '<tr><td align="center" valign="top">'.&mt('Role').'<br />'.$roleselector.'</td>'."\n".
! 823: '<td'.$seccolspan.' align="center" valign="top">'.&mt('Section(s)').'<br />'.$sectionselector.'</td>'."\n".
! 824: '</tr></table>'.&Apache::lonhtmlcommon::row_closure();
! 825: }
! 826: $output .= &Apache::lonhtmlcommon::row_title(&mt('Add another?')).
! 827: '<input name="persontotal" type="hidden" value="'.$persontotal.'" />'.
! 828: '<input name="addperson" type="checkbox" value="'.$persontotal.'"'.
! 829: ' onclick="javascript:nextPage(document.'.$formname.",'".$env{'form.state'}.
! 830: "'".');" />'.&mt('Add?').&Apache::lonhtmlcommon::row_closure(1).
! 831: &Apache::lonhtmlcommon::end_pick_box().'</div>';
! 832: return $output;
! 833: }
! 834:
1.1 raeburn 835: sub print_request_status {
836: return;
837: }
838:
839: sub print_request_logs {
840: return;
841: }
842:
843: sub print_review {
844: my ($r,$state,$dom) = @_;
845: return;
846: }
847:
848: sub courseinfo_form {
1.2 ! raeburn 849: my ($dom,$formname,$crstype) = @_;
! 850: my $output = '<div>'.&Apache::lonhtmlcommon::start_pick_box().
! 851: &Apache::lonhtmlcommon::row_title('Course Description').
! 852: '<input type="text" size="40" name="cdescr" />'.
! 853: &Apache::lonhtmlcommon::row_closure(1).
! 854: &Apache::lonhtmlcommon::end_pick_box().'</div>'.
! 855: '<div>'.&clone_form($dom,$formname,$crstype).'</div>'."\n";
1.1 raeburn 856: return $output;
857: }
858:
859: sub clone_form {
860: my ($dom,$formname,$crstype) = @_;
861: my $type = 'Course';
862: if ($crstype eq 'community') {
863: $type = 'Community';
864: }
865: my $cloneform = &Apache::loncommon::select_dom_form($dom,'clonedomain').
1.2 ! raeburn 866: &Apache::loncommon::selectcourse_link($formname,'clonecourse','clonedomain','','','',$type);
1.1 raeburn 867: my %lt = &Apache::lonlocal::texthash(
868: 'cid' => 'Course ID',
869: 'dmn' => 'Domain',
870: 'dsh' => 'Date Shift',
871: 'ncd' => 'Do not clone date parameters',
872: 'prd' => 'Clone date parameters as-is',
873: 'shd' => 'Shift date parameters by number of days',
874: );
1.2 ! raeburn 875: my $output .=
! 876: &Apache::lonhtmlcommon::start_pick_box().
! 877: &Apache::lonhtmlcommon::row_title($lt{'cid'}).'<label>'.
! 878: '<input type="text" size="25" name="clonecourse" value="" onfocus="this.blur();'.
! 879: 'opencrsbrowser('."'$formname','clonecourse','clonedomain','','','','$type'".');" />'.
! 880: '</label>'.&Apache::lonhtmlcommon::row_closure(1).'<label>'.
! 881: &Apache::lonhtmlcommon::row_title($lt{'dmn'}).'</label>'.
! 882: $cloneform.'</label>'.&Apache::lonhtmlcommon::row_closure().
! 883: &Apache::lonhtmlcommon::row_title($lt{'dsh'}).'<label>'.
! 884: '<input type="radio" name="datemode" value="delete" /> '.$lt{'ncd'}.
! 885: '</label><br /><label>'.
! 886: '<input type="radio" name="datemode" value="preserve" /> '.$lt{'prd'}.
! 887: '</label><br /><label>'.
! 888: '<input type="radio" name="datemode" value="shift" checked="checked" /> '.
! 889: $lt{'shd'}.'</label>'.
! 890: '<input type="text" size="5" name="dateshift" value="365" />'.
! 891: &Apache::lonhtmlcommon::row_closure(1).
! 892: &Apache::lonhtmlcommon::end_pick_box();
1.1 raeburn 893: return $output;
894: }
895:
896: sub coursecode_form {
1.2 ! raeburn 897: my ($dom,$context,$codetitles,$cat_titles,$cat_order,$num) = @_;
1.1 raeburn 898: my $output;
1.2 ! raeburn 899: my %rowtitle = (
! 900: instcode => 'Course Category',
! 901: crosslist => 'Cross Listed Course',
! 902: );
1.1 raeburn 903: if ((ref($codetitles) eq 'ARRAY') && (ref($cat_titles) eq 'HASH') &&
904: (ref($cat_order))) {
1.2 ! raeburn 905: my ($sel,$instsec,$lcsec);
! 906: $sel = $context;
! 907: if ($context eq 'crosslist') {
! 908: $sel .= '_'.$num;
! 909: $instsec = &mt('Institutional section').'<br />'.
! 910: '<input type="text" size="10" name="'.$sel.'_instsec" />';
! 911: $lcsec = &mt('LON-CAPA section').'<br />'.
! 912: '<input type="text" size="10" name="'.$sel.'_lcsec" />';
! 913: }
1.1 raeburn 914: if (@{$codetitles} > 0) {
915: my $lastitem = pop(@{$codetitles});
1.2 ! raeburn 916: my $lastinput = '<input type="text" size="5" name="'.$sel.'_'. $lastitem.'" />';
1.1 raeburn 917: if (@{$codetitles} > 0) {
1.2 ! raeburn 918: $output = &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
! 919: '<table><tr>';
1.1 raeburn 920: if ($context eq 'crosslist') {
1.2 ! raeburn 921: $output .= '<td>'.&mt('Include?').'<br />'.
! 922: '<input type="checkbox" name="'.$sel.'" value="1" /></td>';
1.1 raeburn 923: }
924: foreach my $title (@{$codetitles}) {
925: if (ref($cat_order->{$title}) eq 'ARRAY') {
926: if (@{$cat_order->{$title}} > 0) {
927: $output .= '<td align="center">'.$title.'<br />'."\n".
928: '<select name="'.$sel.'_'.$title.'">'."\n".
929: ' <option value="" selected="selected">'.
930: &mt('Select').'</option>'."\n";
931: foreach my $item (@{$cat_order->{$title}}) {
932: my $longitem = $item;
933: if (ref($cat_titles->{$title}) eq 'HASH') {
934: if ($cat_titles->{$title}{$item} ne '') {
935: $longitem = $cat_titles->{$title}{$item};
936: }
937: }
938: $output .= '<option value="'.$item.'">'.$longitem.
939: '</option>'."\n";
940: }
941: }
942: $output .= '</select></td>'."\n";
943: }
944: }
945: if ($context eq 'crosslist') {
946: $output .= '<td align="center">'.$lastitem.'<br />'."\n".
1.2 ! raeburn 947: $lastinput.'</td><td align="center">'.$instsec.'</td>'.
! 948: '<td align="center">'.$lcsec.'</td></tr></table>';
1.1 raeburn 949: } else {
950: $output .= '</tr></table>'.
951: &Apache::lonhtmlcommon::row_closure().
952: &Apache::lonhtmlcommon::row_title('Course '.$lastitem).
953: $lastinput;
954: }
955: } else {
956: if ($context eq 'crosslist') {
957: $output .= &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
1.2 ! raeburn 958: '<table><tr>'.
! 959: '<td align="center">'.$lastitem.'<br />'.$lastinput.'</td>'.
! 960: '<td align="center">'.$instsec.'</td><td>'.$lcsec.'</td>'.
! 961: '</tr></table>';
1.1 raeburn 962: } else {
963: $output .= &Apache::lonhtmlcommon::row_title('Course '.$lastitem).
964: $lastinput;
965: }
966: }
1.2 ! raeburn 967: $output .= &Apache::lonhtmlcommon::row_closure(1);
! 968: push(@$codetitles,$lastitem);
! 969: } elsif ($context eq 'crosslist') {
! 970: $output .= &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
! 971: '<table><tr><td align="center">'.
! 972: '<span class="LC_nobreak">'.&mt('Include?').
! 973: '<input type="checkbox" name="'.$sel.'" value="1" /></span>'.
! 974: '</td><td align="center">'.&mt('Institutional ID').'<br />'.
! 975: '<input type="text" size="10" name="'.$sel.'_instsec" />'.
! 976: '</td><td align="center">'.$lcsec.'</td></tr></table>'.
! 977: &Apache::lonhtmlcommon::row_closure(1);
1.1 raeburn 978: }
979: }
980: return $output;
981: }
982:
983: sub get_course_dom {
984: my $codedom = &Apache::lonnet::default_login_domain();
985: if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne 'public')) {
986: $codedom = $env{'user.domain'};
987: if ($env{'request.role.domain'} ne '') {
988: $codedom = $env{'request.role.domain'};
989: }
990: }
991: if ($env{'form.showdom'} ne '') {
992: if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') {
993: $codedom = $env{'form.showdom'};
994: }
995: }
996: return $codedom;
997: }
998:
999: sub display_navbuttons {
1000: my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_;
1001: $r->print('<div class="LC_navbuttons">');
1002: if ($prev) {
1003: $r->print('
1004: <input type="button" name="previous" value = "'.$prevtext.'"
1005: onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>
1006: ');
1007: } elsif ($prevtext) {
1008: $r->print('
1009: <input type="button" name="previous" value = "'.$prevtext.'"
1010: onclick="javascript:history.back()"/>
1011: ');
1012: }
1013: if ($next) {
1014: $r->print('
1015: <input type="button" name="next" value="'.$nexttext.'"
1016: onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />');
1017: }
1018: $r->print('</div>');
1019: }
1020:
1021: sub print_request_outcome {
1022: return;
1023: }
1024:
1.2 ! raeburn 1025: sub retrieve_settings {
! 1026: my ($dom,$request_id) = @_;
! 1027: my %reqinfo = &get_request_settings($request_id,$dom);
! 1028: my %stored;
! 1029: $stored{'cdescr'} = &unescape($reqinfo{'description'});
! 1030: $stored{'startaccess'} = $reqinfo{'startaccess'};
! 1031: $stored{'endaccess'} = $reqinfo{'endaccess'};
! 1032: if ($stored{'endaccess'} == 0) {
! 1033: $stored{'no_end_date'} = 1;
! 1034: }
! 1035: $stored{'startenroll'} = $reqinfo{'startenroll'};
! 1036: $stored{'endenroll'} = $reqinfo{'endenroll'};
! 1037: $stored{'crosslist'} = $reqinfo{'crosslist'};
! 1038: $stored{'clonecourse'} = $reqinfo{'clonecourse'};
! 1039: $stored{'clonedomain'} = $reqinfo{'clonedomain'};
! 1040: $stored{'sections'} = $reqinfo{'sections'};
! 1041: $stored{'personnel'} = $reqinfo{'personnel'};
! 1042:
! 1043: return %stored;
! 1044: }
! 1045:
! 1046: sub get_request_settings {
! 1047: my ($request_id,$dom);
! 1048: }
! 1049:
1.1 raeburn 1050: 1;
1051:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>