1: # The LearningOnline Network
2: # Request a course
3: #
4: # $Id: lonrequestcourse.pm,v 1.1 2009/07/27 22:58:24 raeburn Exp $
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:
70: my $action = $env{'form.action'};
71: my $state = $env{'form.state'};
72: my $dom = &get_course_dom();
73: my %can_request;
74: my $canreq = &check_can_request($dom,\%can_request);
75: if ($action eq 'new') {
76: if ($canreq) {
77: if ($state eq 'crstype') {
78: &print_main_menu($r,\%can_request,$dom);
79: } else {
80: &request_administration($r,$action,$state,$dom);
81: }
82: } else {
83: $r->print(&Apache::loncommon::start_page('Course Requests').
84: '<div class="LC_warning">'.
85: &mt('You do not have privileges to request creation of courses.').
86: '</div>'.
87: &Apache::loncommon::end_page());
88: }
89: } elsif ($action eq 'view') {
90: &print_request_status();
91: } elsif ($action eq 'log') {
92: &print_request_logs();
93: } else {
94: &print_main_menu($r,\%can_request,$dom);
95: }
96: return OK;
97: }
98:
99: sub check_can_request {
100: my ($dom,$can_request) = @_;
101: my $canreq = 0;
102: if (ref($can_request) eq 'HASH') {
103: foreach my $type ('official','unofficial','community') {
104: if (&Apache::lonnet::usertools_access($env{'user.name'},
105: $env{'user.domain'},
106: $type,undef,'requestcourses')) {
107: $canreq ++;
108: if ($dom eq $env{'user.domain'}) {
109: $can_request->{$type} = 1;
110: }
111: }
112: if ($env{'environment.reqcrsotherdom.'.$type} ne '') {
113: my @curr = split(',',$env{'environment.reqcrsotherdom.'.$type});
114: if (@curr > 0) {
115: $canreq ++;
116: unless ($dom eq $env{'user.domain'}) {
117: if (grep(/^\Q$dom\E$/,@curr)) {
118: $can_request->{$type} = 1;
119: }
120: }
121: }
122: }
123: }
124: }
125: return $canreq;
126: }
127:
128: sub print_main_menu {
129: my ($r,$can_request,$dom) = @_;
130: my $onchange;
131: unless ($env{'form.interface'} eq 'textual') {
132: $onchange = 1;
133: }
134:
135: &Apache::lonhtmlcommon::clear_breadcrumbs();
136:
137: my $js = <<END;
138: <script type="text/javascript">
139:
140: function nextPage(formname,nextstate) {
141: if (check_can_request() == true) {
142: formname.state.value= nextstate;
143: formname.submit();
144: }
145: return;
146: }
147:
148: function backPage(formname,prevstate) {
149: formname.state.value = prevstate;
150: formname.submit();
151: }
152:
153: function check_can_request() {
154: var official = '';
155: var unofficial = '';
156: var community = '';
157: END
158:
159: foreach my $item (keys(%{$can_request})) {
160: $js .= "
161: $item = 1;
162: ";
163: }
164: my %lt = &Apache::lonlocal::texthash(
165: official => 'You are not permitted to request creation of an official course in this domain.',
166: unofficial => 'You are not permitted to request creation of an unofficial course in this domain.',
167: community => 'You are not permitted to request creation of a community this domain.',
168: all => 'You must choose a specific course type when making a new course request.\\nAll types is not allowed.',
169: );
170: $js .= <<END;
171: var crschoice = document.requestform.crstype.value;
172: if (crschoice == 'official') {
173: if (official != 1) {
174: alert("$lt{'official'}");
175: return false;
176: }
177: } else {
178: if (crschoice == 'unofficial') {
179: if (unofficial != 1) {
180: alert("$lt{'unofficial'}");
181: return false;
182: }
183: } else {
184: if (crschoice == 'community') {
185: if (community != 1) {
186: alert("$lt{'community'}");
187: return false;
188: }
189: } else {
190: var actionchoice = document.requestform.action.value;
191: if (actionchoice == 'new') {
192: alert("$lt{'all'}");
193: return false;
194: }
195: }
196: }
197: }
198: return true;
199: }
200: </script>
201:
202: END
203:
204: my $formname = 'requestform';
205: $r->print(&Apache::loncommon::start_page('Course Requests',$js).
206: '<p><div>'.
207: '<form name="domforcourse" method="post" action="/adm/requestcourse">'.
208: &Apache::lonhtmlcommon::start_pick_box().
209: &Apache::lonhtmlcommon::row_title('Domain').
210: &Apache::loncommon::select_dom_form($dom,'showdom','',1,$onchange));
211: if (!$onchange) {
212: $r->print(' <input type="submit" name="godom" value="'.
213: &mt('Change').'" />');
214: }
215: $r->print(&Apache::lonhtmlcommon::row_closure(1).
216: &Apache::lonhtmlcommon::end_pick_box().'</form></div>');
217:
218: my $formname = 'requestform';
219: my $next = 'codepick';
220: my $nexttext = &mt('Next');
221: $r->print('<div><form name="'.$formname.'" method="post" action="/adm/requestcourse">'.
222: &Apache::lonhtmlcommon::start_pick_box().
223: &Apache::lonhtmlcommon::row_title('Action').'
224: <input type="hidden" name="showdom" value="'.$dom.'" />
225: <select size="1" name="action" >
226: <option value="new">'.&mt('New course request').'</option>
227: <option value="view">'.&mt('View/Modify/Cancel pending requests').'</option>
228: <option value="log">'.&mt('View request history').'</option>
229: </select>'.
230: &Apache::lonhtmlcommon::row_closure().
231: &Apache::lonhtmlcommon::row_title('Course Type').'
232: <select size="1" name="crstype">
233: <option value="any">'.&mt('All types').'</option>
234: <option value="official">'.&mt('Official course').'</option>
235: <option value="unofficial">'.&mt('Unofficial course').'</option>
236: <option value="community">'.&mt('Community').'</option>
237: </select>
238: <input type="hidden" name="state" value="crstype" />'.
239: &Apache::lonhtmlcommon::row_closure(1).
240: &Apache::lonhtmlcommon::end_pick_box().'<br />
241: <input type="button" name="next" value="'.$nexttext.'" onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />
242: </form></div>');
243: $r->print(&Apache::loncommon::end_page());
244: return;
245: }
246:
247: sub request_administration {
248: my ($r,$action,$state,$dom) = @_;
249: if ($action eq 'new') {
250: my $js = <<END;
251: <script type="text/javascript">
252:
253: function nextPage(formname,nextstate) {
254: formname.state.value= nextstate;
255: formname.submit();
256: }
257: function backPage(formname,prevstate) {
258: formname.state.value = prevstate;
259: formname.submit();
260: }
261:
262: </script>
263:
264: END
265:
266: unless (($state eq 'review') || ($state eq 'process')) {
267: $js .= "\n".&Apache::loncommon::coursebrowser_javascript($dom);
268: }
269: my $start_page =
270: &Apache::loncommon::start_page('Request a course',$js);
271: $r->print($start_page);
272: if ($state eq 'review') {
273: &print_review($r,$state,$dom);
274: } elsif ($state eq 'process') {
275: &print_request_outcome($r,$state,$dom);
276: } else {
277: &print_request_form($r,$state,$dom);
278: }
279: $r->print(&Apache::loncommon::end_page());
280: } elsif ($action eq 'log') {
281: $r->print(&coursereq_log());
282: }
283: return;
284: }
285:
286: sub print_request_form {
287: my ($r,$state,$dom) = @_;
288: my $formname = 'requestcrs';
289: my ($next,$prev,$message,$output,$codepicker);
290: my $prev = 'crstype';
291: $r->print('<form name="'.$formname.'" method="post" action="/adm/requestcourse">');
292: my $crstype = $env{'form.crstype'};
293: my $xlist = 0;
294: if ($crstype eq 'official') {
295: my (@codetitles,%cat_titles,%cat_order,@code_order);
296: &Apache::lonnet::auto_possible_instcodes($dom,\@codetitles,\%cat_titles,
297: \%cat_order,\@code_order);
298: if ($state eq 'courseinfo') {
299: my $instcode;
300: if (@code_order > 0) {
301: foreach my $item (@code_order) {
302: $instcode .= $env{'form.instcode_'.$item};
303: }
304: }
305: if ($instcode ne '') {
306: my $code_chk = &Apache::lonnet::auto_validate_instcode('',$dom,$instcode);
307: if ($code_chk eq 'ok') {
308: $message = '<div class="LC_info">'.
309: &mt('The chosen course category [_1] is valid.','<b>'.
310: $instcode.'</b>').'</div>';
311: my @sections = &Apache::lonnet::auto_get_sections(undef,$dom,
312: $instcode);
313: if (@sections) {
314: $output .= &inst_section_selector(\@sections);
315: }
316: $output .= &coursecode_form($dom,'crosslist',\@codetitles,
317: \%cat_titles,\%cat_order,$xlist);
318: $prev = 'codepick';
319: } else {
320: $message = '<div class="LC_warning">'.
321: &mt('No course was found matching your choice of institutional course category.');
322: if ($code_chk ne '') {
323: $message .= '<br />'.$code_chk;
324: }
325: $message .= '</div>';
326: }
327: }
328: }
329: unless ($prev eq 'codepick') {
330: $codepicker = &coursecode_form($dom,'instcode',\@codetitles,
331: \%cat_titles,\%cat_order);
332: }
333: }
334: $r->print($message.'<div>'.&Apache::lonhtmlcommon::start_pick_box());
335: if ($output ne '') {
336: $r->print($output);
337: }
338: if ($codepicker) {
339: $r->print($codepicker);
340: $state = 'codepick';
341: $next = 'courseinfo';
342: } else {
343: $r->print(&courseinfo_form());
344: $state = 'courseinfo';
345: $next = 'review';
346: }
347: $r->print(&Apache::lonhtmlcommon::end_pick_box().'</div>'."\n");
348: unless ($codepicker) {
349: $r->print('<div>'.&clone_form($dom,$formname,$crstype).'</div>'."\n");
350: }
351: $r->print('<input type="hidden" name="state" value="'.$state.'" />'.
352: &Apache::lonhtmlcommon::echo_form_input(['state']).'</form>');
353: &display_navbuttons($r,$formname,$prev,'Previous',$next,'Next');
354: return;
355: }
356:
357: sub inst_section_selector {
358: my ($sections,$selected) = @_;
359: my $output;
360: if (ref($sections) eq 'ARRAY') {
361: $output = &Apache::lonhtmlcommon::row_title('Sections').
362: &Apache::loncommon::start_data_table().
363: &Apache::loncommon::start_data_table_row().
364: '<th>'.&mt('Institutional Section').'</th>'.
365: '<th>'.&mt('LON-CAPA section ID').'</th>'.
366: '<th>'.&mt('Include in course?').'</th>'.
367: &Apache::loncommon::end_data_table_row();
368: for (my $i=0; $i<@{$sections}; $i++) {
369: my $colflag = $i%2;
370: $output .= &Apache::loncommon::start_data_table_row().
371: '<td>'.$sections->[$i].
372: '<input type="hidden" name="secnum_'.$i.'" value="'.
373: $sections->[$i].'" /></td>'.
374: '<td><input type="text" size="10" name="loncapasec_'.$i.
375: '" value="'.$sections->[$i].'" /></td>'.
376: '<td><input type="checkbox" name="sec_'.$i.
377: '" checked="checked" /></td>'.
378: &Apache::loncommon::end_data_table_row();
379: }
380: $output .= &Apache::loncommon::end_data_table();
381: }
382: return $output;
383: }
384:
385: sub print_request_status {
386: return;
387: }
388:
389: sub print_request_logs {
390: return;
391: }
392:
393: sub print_review {
394: my ($r,$state,$dom) = @_;
395: return;
396: }
397:
398: sub courseinfo_form {
399: my $output = &Apache::lonhtmlcommon::row_title('Course Description').
400: '<input type="text" size="40" name="description" />';
401: return $output;
402: }
403:
404: sub clone_form {
405: my ($dom,$formname,$crstype) = @_;
406: my $type = 'Course';
407: if ($crstype eq 'community') {
408: $type = 'Community';
409: }
410: my $cloneform = &Apache::loncommon::select_dom_form($dom,'clonedomain').
411: &Apache::loncommon::selectcourse_link($formname,'clonecourse',
412: 'clonedomain','','','',$type);
413: my %lt = &Apache::lonlocal::texthash(
414: 'cid' => 'Course ID',
415: 'dmn' => 'Domain',
416: 'dsh' => 'Date Shift',
417: 'ncd' => 'Do not clone date parameters',
418: 'prd' => 'Clone date parameters as-is',
419: 'shd' => 'Shift date parameters by number of days',
420: );
421: my $output .= &Apache::lonhtmlcommon::start_pick_box().
422: &Apache::lonhtmlcommon::row_title($lt{'cid'}).
423: '<label><input type="text" size="25" name="clonecourse" value="" />'.
424: '</label>'.&Apache::lonhtmlcommon::row_closure(1).'<label>'.
425: &Apache::lonhtmlcommon::row_title($lt{'dmn'}).'</label>'.
426: $cloneform.'</label>'.&Apache::lonhtmlcommon::row_closure().
427: &Apache::lonhtmlcommon::row_title($lt{'dsh'}).'<label>'.
428: '<input type="radio" name="datemode" value="delete" /> '.$lt{'ncd'}.
429: '</label><br /><label>'.
430: '<input type="radio" name="datemode" value="preserve" /> '.$lt{'prd'}.
431: '</label><br /><label>'.
432: '<input type="radio" name="datemode" value="shift" checked="checked" /> '.
433: $lt{'shd'}.'</label>'.
434: '<input type="text" size="5" name="dateshift" value="365" />'.
435: &Apache::lonhtmlcommon::row_closure(1).
436: &Apache::lonhtmlcommon::end_pick_box();
437: return $output;
438: }
439:
440: sub coursecode_form {
441: my ($dom,$context,$codetitles,$cat_titles,$cat_order,$count) = @_;
442: my $output;
443: if ((ref($codetitles) eq 'ARRAY') && (ref($cat_titles) eq 'HASH') &&
444: (ref($cat_order))) {
445: if (@{$codetitles} > 0) {
446: my $lastitem = pop(@{$codetitles});
447: my $sel = $context;
448: if ($context eq 'crosslist') {
449: $sel .= '_'.$count;
450: }
451: my $lastinput = '<input type="text" size="5" name="'.$sel.'_'. $lastitem.'" />';
452: my %rowtitle = (
453: instcode => 'Course Category',
454: crosslist => 'Cross Listed Course',
455: );
456: if (@{$codetitles} > 0) {
457: my $sel = $context;
458: if ($context eq 'crosslist') {
459: $sel .= '_'.$count;
460: }
461: $output = &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
462: '<table><tr>';
463: foreach my $title (@{$codetitles}) {
464: if (ref($cat_order->{$title}) eq 'ARRAY') {
465: if (@{$cat_order->{$title}} > 0) {
466: $output .= '<td align="center">'.$title.'<br />'."\n".
467: '<select name="'.$sel.'_'.$title.'">'."\n".
468: ' <option value="" selected="selected">'.
469: &mt('Select').'</option>'."\n";
470: foreach my $item (@{$cat_order->{$title}}) {
471: my $longitem = $item;
472: if (ref($cat_titles->{$title}) eq 'HASH') {
473: if ($cat_titles->{$title}{$item} ne '') {
474: $longitem = $cat_titles->{$title}{$item};
475: }
476: }
477: $output .= '<option value="'.$item.'">'.$longitem.
478: '</option>'."\n";
479: }
480: }
481: $output .= '</select></td>'."\n";
482: }
483: }
484: if ($context eq 'crosslist') {
485: $output .= '<td align="center">'.$lastitem.'<br />'."\n".
486: $lastinput.'</td></tr></table>';
487: } else {
488: $output .= '</tr></table>'.
489: &Apache::lonhtmlcommon::row_closure().
490: &Apache::lonhtmlcommon::row_title('Course '.$lastitem).
491: $lastinput;
492: }
493: } else {
494: if ($context eq 'crosslist') {
495: $output .= &Apache::lonhtmlcommon::row_title($rowtitle{$context}).
496: $lastitem.'<br />';
497: } else {
498: $output .= &Apache::lonhtmlcommon::row_title('Course '.$lastitem).
499: $lastinput;
500: }
501: $output .= $lastinput.&Apache::lonhtmlcommon::row_closure(1);
502: }
503: }
504: }
505: return $output;
506: }
507:
508: sub get_course_dom {
509: my $codedom = &Apache::lonnet::default_login_domain();
510: if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne 'public')) {
511: $codedom = $env{'user.domain'};
512: if ($env{'request.role.domain'} ne '') {
513: $codedom = $env{'request.role.domain'};
514: }
515: }
516: if ($env{'form.showdom'} ne '') {
517: if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') {
518: $codedom = $env{'form.showdom'};
519: }
520: }
521: return $codedom;
522: }
523:
524: sub display_navbuttons {
525: my ($r,$formname,$prev,$prevtext,$next,$nexttext) = @_;
526: $r->print('<div class="LC_navbuttons">');
527: if ($prev) {
528: $r->print('
529: <input type="button" name="previous" value = "'.$prevtext.'"
530: onclick="javascript:backPage(document.'.$formname.','."'".$prev."'".')"/>
531: ');
532: } elsif ($prevtext) {
533: $r->print('
534: <input type="button" name="previous" value = "'.$prevtext.'"
535: onclick="javascript:history.back()"/>
536: ');
537: }
538: if ($next) {
539: $r->print('
540: <input type="button" name="next" value="'.$nexttext.'"
541: onclick="javascript:nextPage(document.'.$formname.','."'".$next."'".')" />');
542: }
543: $r->print('</div>');
544: }
545:
546: sub print_request_outcome {
547: return;
548: }
549:
550: 1;
551:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>