Annotation of loncom/interface/loncreatecourse.pm, revision 1.91
1.65 raeburn 1: # The LearningOnline Network
1.1 www 2: # Create a course
1.5 albertel 3: #
1.91 ! albertel 4: # $Id: loncreatecourse.pm,v 1.90 2006/05/30 20:05:05 raeburn Exp $
1.5 albertel 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: #
1.48 www 28: ###
29:
1.1 www 30: package Apache::loncreatecourse;
31:
32: use strict;
33: use Apache::Constants qw(:common :http);
34: use Apache::lonnet;
1.12 www 35: use Apache::loncommon;
1.13 www 36: use Apache::lonratedt;
37: use Apache::londocs;
1.38 www 38: use Apache::lonlocal;
1.41 raeburn 39: use Apache::londropadd;
1.90 raeburn 40: use LONCAPA::batchcreatecourse;
1.44 raeburn 41: use lib '/home/httpd/lib/perl';
1.89 www 42: use LONCAPA;
1.28 www 43:
44: # ================================================ Get course directory listing
45:
1.62 www 46: my @output=();
47:
1.28 www 48: sub crsdirlist {
49: my ($courseid,$which)=@_;
1.62 www 50: @output=();
51: return &innercrsdirlist($courseid,$which);
52: }
53:
54: sub innercrsdirlist {
55: my ($courseid,$which,$path)=@_;
56: my $dirptr=16384;
1.63 www 57: unless ($which) { $which=''; } else { $which.='/'; }
58: unless ($path) { $path=''; } else { $path.='/'; }
1.28 www 59: my %crsdata=&Apache::lonnet::coursedescription($courseid);
60: my @listing=&Apache::lonnet::dirlist
61: ($which,$crsdata{'domain'},$crsdata{'num'},
1.89 www 62: &propath($crsdata{'domain'},$crsdata{'num'}));
1.28 www 63: foreach (@listing) {
64: unless ($_=~/^\./) {
1.62 www 65: my @unpackline = split (/\&/,$_);
66: if ($unpackline[3]&$dirptr) {
67: # is a directory, recurse
1.63 www 68: &innercrsdirlist($courseid,$which.$unpackline[0],
69: $path.$unpackline[0]);
1.62 www 70: } else {
71: # is a file, put into output
1.63 www 72: push (@output,$path.$unpackline[0]);
1.62 www 73: }
1.28 www 74: }
75: }
76: return @output;
1.29 www 77: }
78:
79: # ============================================================= Read a userfile
80:
81: sub readfile {
82: my ($courseid,$which)=@_;
83: my %crsdata=&Apache::lonnet::coursedescription($courseid);
84: return &Apache::lonnet::getfile('/uploaded/'.$crsdata{'domain'}.'/'.
85: $crsdata{'num'}.'/'.$which);
86: }
87:
88: # ============================================================ Write a userfile
89:
90: sub writefile {
1.78 albertel 91: (my $courseid, my $which,$env{'form.output'})=@_;
1.29 www 92: my %crsdata=&Apache::lonnet::coursedescription($courseid);
93: return &Apache::lonnet::finishuserfileupload(
94: $crsdata{'num'},$crsdata{'domain'},
95: 'output',$which);
96: }
97:
1.36 www 98: # ===================================================================== Rewrite
99:
100: sub rewritefile {
101: my ($contents,%rewritehash)=@_;
102: foreach (keys %rewritehash) {
103: my $pattern=$_;
104: $pattern=~s/(\W)/\\$1/gs;
105: my $new=$rewritehash{$_};
106: $contents=~s/$pattern/$new/gs;
107: }
108: return $contents;
109: }
110:
1.29 www 111: # ============================================================= Copy a userfile
112:
113: sub copyfile {
114: my ($origcrsid,$newcrsid,$which)=@_;
1.36 www 115: unless ($which=~/\.sequence$/) {
116: return &writefile($newcrsid,$which,
117: &readfile($origcrsid,$which));
118: } else {
119: my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
120: my %newcrsdata= &Apache::lonnet::coursedescription($newcrsid);
121: return &writefile($newcrsid,$which,
122: &rewritefile(
123: &readfile($origcrsid,$which),
124: (
125: '/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'
1.66 albertel 126: => '/uploaded/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/',
127: '/public/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'
128: => '/public/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/'
1.36 www 129: )));
130: }
1.30 www 131: }
132:
133: # =============================================================== Copy a dbfile
134:
135: sub copydb {
136: my ($origcrsid,$newcrsid,$which)=@_;
137: $which=~s/\.db$//;
138: my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
139: my %newcrsdata= &Apache::lonnet::coursedescription($newcrsid);
140: my %data=&Apache::lonnet::dump
141: ($which,$origcrsdata{'domain'},$origcrsdata{'num'});
1.72 albertel 142: foreach my $key (keys(%data)) {
143: if ($key=~/^internal./) { delete($data{$key}); }
144: }
1.30 www 145: return &Apache::lonnet::put
146: ($which,\%data,$newcrsdata{'domain'},$newcrsdata{'num'});
147: }
148:
1.35 www 149: # ========================================================== Copy resourcesdata
150:
151: sub copyresourcedb {
152: my ($origcrsid,$newcrsid)=@_;
153: my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
154: my %newcrsdata= &Apache::lonnet::coursedescription($newcrsid);
155: my %data=&Apache::lonnet::dump
156: ('resourcedata',$origcrsdata{'domain'},$origcrsdata{'num'});
157: $origcrsid=~s/^\///;
158: $origcrsid=~s/\//\_/;
159: $newcrsid=~s/^\///;
160: $newcrsid=~s/\//\_/;
161: my %newdata=();
162: undef %newdata;
163: my $startdate=$data{$origcrsid.'.0.opendate'};
1.85 albertel 164: if (!$startdate) {
165: # now global start date for assements try the enrollment start
166: my %start=&Apache::lonnet::get('environment',
167: ['default_enrollment_start_date'],
168: $origcrsdata{'domain'},$origcrsdata{'num'});
169:
170: $startdate = $start{'default_enrollment_start_date'};
171: }
1.35 www 172: my $today=time;
173: my $delta=0;
174: if ($startdate) {
175: my $oneday=60*60*24;
176: $delta=$today-$startdate;
177: $delta=int($delta/$oneday)*$oneday;
178: }
179: # ugly retro fix for broken version of types
180: foreach (keys %data) {
181: if ($_=~/\wtype$/) {
182: my $newkey=$_;
183: $newkey=~s/type$/\.type/;
184: $data{$newkey}=$data{$_};
185: delete $data{$_};
186: }
187: }
1.37 www 188: # adjust symbs
189: my $pattern='uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/';
190: $pattern=~s/(\W)/\\$1/gs;
191: my $new= 'uploaded/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/';
192: foreach (keys %data) {
193: if ($_=~/$pattern/) {
194: my $newkey=$_;
195: $newkey=~s/$pattern/$new/;
196: $data{$newkey}=$data{$_};
197: delete $data{$_};
198: }
199: }
1.35 www 200: # adjust dates
201: foreach (keys %data) {
202: my $thiskey=$_;
203: $thiskey=~s/^$origcrsid/$newcrsid/;
204: $newdata{$thiskey}=$data{$_};
1.75 albertel 205: if ($data{$_.'.type'}=~/^date_(start|end)$/) {
1.85 albertel 206: if ($delta > 0) {
207: $newdata{$thiskey}=$newdata{$thiskey}+$delta;
208: } else {
209: # no delta, it's unlikely we want the old dates and times
210: delete($newdata{$thiskey});
211: delete($newdata{$thiskey.'.type'});
212: }
1.35 www 213: }
214: }
215: return &Apache::lonnet::put
216: ('resourcedata',\%newdata,$newcrsdata{'domain'},$newcrsdata{'num'});
217: }
218:
1.30 www 219: # ========================================================== Copy all userfiles
220:
221: sub copyuserfiles {
222: my ($origcrsid,$newcrsid)=@_;
223: foreach (&crsdirlist($origcrsid,'userfiles')) {
1.69 albertel 224: if ($_ !~m|^scantron_|) {
225: ©file($origcrsid,$newcrsid,$_);
226: }
1.30 www 227: }
228: }
229: # ========================================================== Copy all userfiles
230:
231: sub copydbfiles {
232: my ($origcrsid,$newcrsid)=@_;
1.82 albertel 233:
234: my ($origcrs_discussion) = ($origcrsid=~m|^/(.*)|);
235: $origcrs_discussion=~s|/|_|g;
1.30 www 236: foreach (&crsdirlist($origcrsid)) {
237: if ($_=~/\.db$/) {
238: unless
1.88 albertel 239: ($_=~/^(nohist\_|discussiontimes|classlist|versionupdate|resourcedata|\Q$origcrs_discussion\E|slots|slot_reservations|gradingqueue|reviewqueue|CODEs)/) {
1.30 www 240: ©db($origcrsid,$newcrsid,$_);
1.80 www 241: my $histfile=$_;
242: $histfile=~s/\.db$/\.hist/;
243: ©file($origcrsid,$newcrsid,$histfile);
1.30 www 244: }
245: }
246: }
1.31 www 247: }
248:
249: # ======================================================= Copy all course files
250:
251: sub copycoursefiles {
252: my ($origcrsid,$newcrsid)=@_;
253: ©userfiles($origcrsid,$newcrsid);
254: ©dbfiles($origcrsid,$newcrsid);
1.35 www 255: ©resourcedb($origcrsid,$newcrsid);
1.28 www 256: }
1.13 www 257:
1.2 www 258: # ===================================================== Phase one: fill-in form
259:
1.10 matthew 260: sub print_course_creation_page {
1.2 www 261: my $r=shift;
1.90 raeburn 262: my $crstype = 'Group';
263: if ($env{'form.phase'} eq 'courseone') {
264: $crstype = 'Course';
265: }
1.78 albertel 266: my $defdom=$env{'request.role.domain'};
1.10 matthew 267: my %host_servers = &Apache::loncommon::get_library_servers($defdom);
268: my $course_home = '<select name="course_home" size="1">'."\n";
269: foreach my $server (sort(keys(%host_servers))) {
1.14 matthew 270: $course_home .= qq{<option value="$server"};
271: if ($server eq $Apache::lonnet::perlvar{'lonHostID'}) {
272: $course_home .= " selected ";
273: }
274: $course_home .= qq{>$server $host_servers{$server}</option>};
1.10 matthew 275: }
276: $course_home .= "\n</select>\n";
1.9 matthew 277: my $domform = &Apache::loncommon::select_dom_form($defdom,'ccdomain');
1.32 www 278: my $cloneform=&Apache::loncommon::select_dom_form
1.78 albertel 279: ($env{'request.role.domain'},'clonedomain').
1.32 www 280: &Apache::loncommon::selectcourse_link
1.90 raeburn 281: ('ccrs','clonecourse','clonedomain',undef,undef,undef,$crstype);
1.78 albertel 282: my $coursebrowserjs=&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'});
1.90 raeburn 283: my ($enroll_table,$access_table,$krbdef,$krbdefdom,$krbform,$intform,$locform,
284: $javascript_validations);
285: if ($crstype eq 'Course') {
286: my $starttime = time;
287: my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
288: $enroll_table = &Apache::londropadd::date_setting_table($starttime,
289: $endtime,'create_enrolldates');
290: $access_table = &Apache::londropadd::date_setting_table($starttime,
291: $endtime,'create_defaultdates');
292: ($krbdef,$krbdefdom) =
293: &Apache::loncommon::get_kerberos_defaults($defdom);
294: $javascript_validations=&Apache::londropadd::javascript_validations(
295: 'createcourse',$krbdefdom);
296: my %param = ( formname => 'document.ccrs',
297: kerb_def_dom => $krbdefdom,
298: kerb_def_auth => $krbdef
299: );
300: $krbform = &Apache::loncommon::authform_kerberos(%param);
301: $intform = &Apache::loncommon::authform_internal(%param);
302: $locform = &Apache::loncommon::authform_local(%param);
303: } else {
304: $javascript_validations = qq|
305: function validate(formname) {
306: if (formname.title == '') {
307: alert("A group title is required");
308: return;
309: }
310: if (formname.ccuname == '') {
311: alert("The username of the group coordinator is required");
312: }
313: formname.submit();
314: }
315: |;
316: }
1.46 sakharuk 317: my %lt=&Apache::lonlocal::texthash(
318: 'cinf' => "Course Information",
319: 'ctit' => "Course Title",
320: 'chsr' => "Course Home Server",
321: 'cidn' => "Course ID/Number",
322: 'opt' => "optional",
323: 'iinf' => "Institutional Information",
324: 'stat' => "The following entries will be used to identify the course according to the naming scheme adopted by your institution. Your choices will be used to map an internal LON-CAPA course ID to the corresponding course section ID(s) used by the office responsible for providing official class lists for courses at your institution. This mapping is required if you choose to employ automatic population of class lists.",
325: 'ccod' => "Course Code",
326: 'toin' => "to interface with institutional data, e.g., fs03glg231 for Fall 2003 Geology 231",
1.90 raeburn 327: 'snid' => "Section Numbers and corresponding LON-CAPA section IDs",
328: 'csli' => "a comma separated list of institutional section numbers, each separated by a colon from the (optional) corresponding section ID to be used in LON-CAPA e.g., 001:1,002:2",
1.46 sakharuk 329: 'crcs' => "Crosslisted courses",
1.90 raeburn 330: 'cscs' => "a comma separated list of course sections crosslisted with the current course, with each entry including the institutional course section name followed by a colon and then the (optional) sectionID to be used in LON-CAPA, e.g., fs03ent231001:ent1,fs03bot231001:bot1,fs03zol231002:zol2",
1.46 sakharuk 331: 'crco' => "Course Content",
332: 'cncr' => "Completely new course",
333: 'cecr' => "Clone an existing course",
334: 'map' => "Map",
335: 'smap' => "Select Map",
336: 'sacr' => "Do NOT generate as standard course",
337: 'ocik' => "only check if you know what you are doing",
338: 'fres' => "First Resource",
339: 'stco' => "standard courses only",
340: 'blnk' => "Blank",
341: 'sllb' => "Syllabus",
342: 'navi' => "Navigate",
343: 'cid' => "Course ID",
344: 'dmn' => "Domain",
345: 'asov' => "Additional settings, if specified below, will override cloned settings",
346: 'assp' => "Assessment Parameters",
347: 'oaas' => "Open all assessments",
348: 'mssg' => "Messaging",
349: 'scpf' => "Set course policy feedback to Course Coordinator",
350: 'scfc' => "Set content feedback to Course Coordinator",
351: 'cmmn' => "Communication",
352: 'dsrd' => "Disable student resource discussion",
353: 'dsuc' => "Disable student use of chatrooms",
354: 'acco' => "Access Control",
355: 'snak' => "Students need access key to enter course",
1.56 www 356: 'kaut' =>
357: 'Key authority (<tt>id@domain</tt>) if other than course',
1.46 sakharuk 358: 'cc' => "Course Coordinator",
359: 'user' => "Username",
360: 'aens' => "Automated enrollment settings",
361: 'aesc' => "The following settings control automatic enrollment of students in this class based on information available for this specific course from your institution's official classlists.",
362: 'aadd' => "Automated adds",
363: 'yes' => "Yes",
364: 'no' => "No",
365: 'audr' => "Automated drops",
366: 'dacu' => "Duration of automated classlist updates",
1.60 raeburn 367: 'dacc' => "Default start and end dates for student access",
1.46 sakharuk 368: 'psam' => "Please select the authentication mechanism",
369: 'pcda' => "Please choose the default authentication method to be used by new users added to this LON-CAPA domain by the automated enrollment process",
370: 'nech' => "Notification of enrollment changes",
371: 'nccl' => "Notification to course coordinator via LON-CAPA message when enrollment changes occur during the automated update?",
1.77 raeburn 372: 'ndcl' => "Notification to domain coordinator via LON-CAPA message when enrollment changes occur during the automated update?",
1.46 sakharuk 373: 'irsp' => "Include retrieval of student photographs?",
1.55 www 374: 'rshm' => 'Resource Space Home',
1.90 raeburn 375: 'opco' => "Open Course",
376: 'ginf' => "Group Information",
377: 'gtit' => "Group Title",
378: 'ghsr' => "Group Home Server",
379: 'gidn' => "Group ID/Number",
380: 'grco' => "Group Content",
381: 'cngr' => "Completely new group",
382: 'cegr' => "Clone an existing group",
383: 'sagr' => "Do NOT generate as standard group",
384: 'stgo' => "standard groups only",
385: 'sgpf' => "Set group policy feedback to Group Coordinator",
386: 'scfg' => "Set content feedback to Group Coordinator",
387: 'dmrd' => "Disable member resource discussion",
388: 'dmuc' => "Disable member use of chatrooms",
389: 'mnak' => "Members need access key to enter group",
390: 'kaug' =>
391: 'Key authority (<tt>id@domain</tt>) if other than group',
392: 'gc' => "Group Coordinator",
393: 'gid' => "Group ID",
394: 'crgr' => "Create Group",
1.46 sakharuk 395: );
1.90 raeburn 396:
1.86 albertel 397: my $js = <<END;
398: <script type="text/javascript">
1.6 matthew 399: var editbrowser = null;
400: function openbrowser(formname,elementname) {
401: var url = '/res/?';
402: if (editbrowser == null) {
403: url += 'launch=1&';
404: }
405: url += 'catalogmode=interactive&';
406: url += 'mode=edit&';
407: url += 'form=' + formname + '&';
1.7 matthew 408: url += 'element=' + elementname + '&';
409: url += 'only=sequence' + '';
1.6 matthew 410: var title = 'Browser';
411: var options = 'scrollbars=1,resizable=1,menubar=0';
412: options += ',width=700,height=600';
413: editbrowser = open(url,title,options,'1');
414: editbrowser.focus();
415: }
1.41 raeburn 416: $javascript_validations
1.6 matthew 417: </script>
1.32 www 418: $coursebrowserjs
1.86 albertel 419: END
420:
1.90 raeburn 421: my %titles = &Apache::lonlocal::texthash(
422: courseone => 'Create a New Course',
423: groupone => 'Create a New Group',
424: );
1.86 albertel 425: my $start_page =
1.90 raeburn 426: &Apache::loncommon::start_page($titles{$env{'form.phase'}},$js);
1.86 albertel 427: my $end_page =
428: &Apache::loncommon::end_page();
1.91 ! albertel 429: my $crumbs =
! 430: &Apache::lonhtmlcommon::breadcrumbs($crstype.' Information',
! 431: 'Create_Course',undef,
! 432: 'Create_Courses');
1.90 raeburn 433: $r->print($start_page.$crumbs);
434: if ($crstype eq 'Course') {
435: $r->print(<<ENDDOCUMENT);
1.6 matthew 436: <form action="/adm/createcourse" method="post" name="ccrs">
1.46 sakharuk 437: <h2>$lt{'cinf'}</h2>
1.10 matthew 438: <p>
1.68 matthew 439: <label><b>$lt{'ctit'}:</b>
440: <input type="text" size="50" name="title" /></label>
1.10 matthew 441: </p><p>
1.68 matthew 442: <label>
443: <b>$lt{'chsr'}:</b>$course_home
444: </label>
445: </p><p>
446: <label>
447: <b>$lt{'cidn'} ($lt{'opt'})</b>
448: <input type="text" size="30" name="crsid" />
449: </label>
1.40 raeburn 450: </p><p>
1.46 sakharuk 451: <h2>$lt{'iinf'}</h2>
1.40 raeburn 452: <p>
1.46 sakharuk 453: $lt{'stat'}
1.40 raeburn 454: </p><p>
1.68 matthew 455: <label>
456: <b>$lt{'ccod'}</b>
457: <input type="text" size="30" name="crscode" />
458: </label>
459: <br/>
1.46 sakharuk 460: ($lt{'toin'})
1.40 raeburn 461: </p><p>
1.68 matthew 462: <label>
463: <b>$lt{'snid'}</b>
464: <input type="text" size="30" name="crssections" />
465: </label>
466: <br/>
1.46 sakharuk 467: ($lt{'csli'})
1.40 raeburn 468: </p><p>
1.68 matthew 469: <label>
470: <b>$lt{'crcs'}</b>
471: <input type="text" size="30" name="crsxlist" />
472: </label>
473: <br/>
1.46 sakharuk 474: ($lt{'cscs'})
1.13 www 475: </p>
1.46 sakharuk 476: <h2>$lt{'crco'}</h2>
1.32 www 477: <table border="2">
1.46 sakharuk 478: <tr><th>$lt{'cncr'}</th><th>$lt{'cecr'}</th></tr>
1.32 www 479: <tr><td>
1.13 www 480: <p>
1.68 matthew 481: <label>
482: <b>$lt{'map'}:</b>
483: <input type="text" size="50" name="topmap" />
484: </label>
1.46 sakharuk 485: <a href="javascript:openbrowser('ccrs','topmap')">$lt{'smap'}</a>
1.10 matthew 486: </p><p>
1.68 matthew 487: <label for="nonstd"><b>$lt{'sacr'}</b></label>
488: <br />
1.46 sakharuk 489: ($lt{'ocik'}):
1.68 matthew 490: <input id="nonstd" type="checkbox" name="nonstandard" />
491: </p><p>
1.46 sakharuk 492: <b>$lt{'fres'}</b><br />($lt{'stco'}):
1.68 matthew 493: <label>
494: <input type="radio" name="firstres" value="blank" />$lt{'blnk'}
495: </label>
1.13 www 496:
1.68 matthew 497: <label>
498: <input type="radio" name="firstres" value="syl" checked />$lt{'sllb'}
499: </label>
1.13 www 500:
1.68 matthew 501: <label>
502: <input type="radio" name="firstres" value="nav" />$lt{'navi'}
503: </label>
1.13 www 504: </p>
1.32 www 505: </td><td>
1.68 matthew 506: <label>
507: $lt{'cid'}: <input type="text" size="25" name="clonecourse" value="" />
508: </label>
509: <br />
510: <label>
511: $lt{'dmn'}: $cloneform
512: </label>
1.32 www 513: <br />
1.68 matthew 514: <br />
1.46 sakharuk 515: $lt{'asov'}.
1.32 www 516: </td></tr>
517: </table>
1.46 sakharuk 518: <h2>$lt{'assp'}</h2>
1.13 www 519: <p>
1.68 matthew 520: <label>
521: <b>$lt{'oaas'}: </b>
522: <input type="checkbox" name="openall" />
523: </label>
1.13 www 524: </p>
1.46 sakharuk 525: <h2>$lt{'mssg'}</h2>
1.13 www 526: <p>
1.68 matthew 527: <label>
528: <b>$lt{'scpf'}: </b>
529: <input type="checkbox" name="setpolicy" checked />
530: </label>
1.55 www 531: <br />
1.68 matthew 532: <label>
533: <b>$lt{'scfc'}: </b>
534: <input type="checkbox" name="setcontent" checked />
535: </label>
1.11 www 536: </p>
1.46 sakharuk 537: <h2>$lt{'cmmn'}</h2>
1.16 www 538: <p>
1.68 matthew 539: <label>
540: <b>$lt{'dsrd'}: </b>
541: <input type="checkbox" name="disresdis" />
542: </label>
543: <br />
544: <label>
545: <b>$lt{'dsuc'}: </b>
546: <input type="checkbox" name="disablechat" />
547: </label>
1.16 www 548: </p>
1.46 sakharuk 549: <h2>$lt{'acco'}</h2>
1.18 www 550: <p>
1.68 matthew 551: <label>
552: <b>$lt{'snak'}: </b>
553: <input type="checkbox" name="setkeys" />
554: </label>
555: <br />
556: <label>
557: <b>$lt{'kaut'}: </b>
558: <input type="text" size="30" name="keyauth" />
559: </label>
1.18 www 560: </p>
1.55 www 561: <h2>$lt{'rshm'}</h2>
562: <p>
1.68 matthew 563: <label>
564: <b>$lt{'rshm'}: </b>
565: <input type="text" name="reshome" size="30" value="/res/$defdom/" />
566: </label>
1.55 www 567: </p>
1.10 matthew 568: <p>
1.46 sakharuk 569: <h2>$lt{'aens'}</h2>
570: $lt{'aesc'}
1.40 raeburn 571: </p>
572: <p>
1.46 sakharuk 573: <b>$lt{'aadd'}</b>
1.68 matthew 574: <label><input type="radio" name="autoadds" value="1" />$lt{'yes'}</label>
575: <label><input type="radio" name="autoadds" value="0" checked="true" />$lt{'no'}
576: </label>
1.40 raeburn 577: </p><p>
1.46 sakharuk 578: <b>$lt{'audr'}</b>
1.68 matthew 579: <label><input type="radio" name="autodrops" value="1" />$lt{'yes'}</label>
580: <label><input type="radio" name="autodrops" value="0" checked="true" />$lt{'no'}</label>
1.40 raeburn 581: </p><p>
1.46 sakharuk 582: <b>$lt{'dacu'}</b>
1.60 raeburn 583: $enroll_table
1.40 raeburn 584: </p><p>
1.60 raeburn 585: <b>$lt{'dacc'}</b>
586: $access_table
587: <p></p>
1.46 sakharuk 588: <b>$lt{'psam'}.</b><br />
589: $lt{'pcda'}.
1.40 raeburn 590: </p><p>
591: $krbform
592: <br />
593: $intform
594: <br />
595: $locform
596: </p><p>
1.46 sakharuk 597: <b>$lt{'nech'}</b><br />
598: $lt{'nccl'}<br/>
1.68 matthew 599: <label>
1.77 raeburn 600: <input type="radio" name="notify_owner" value="1" />$lt{'yes'}
1.68 matthew 601: </label>
602: <label>
1.77 raeburn 603: <input type="radio" name="notify_owner" value="0" checked="true" />$lt{'no'}
604: </label>
605: <br />
606: $lt{'ndcl'}<br/>
607: <label>
608: <input type="radio" name="notify_dc" value="1" />$lt{'yes'}
609: </label>
610: <label>
611: <input type="radio" name="notify_dc" value="0" checked="true" />$lt{'no'}
1.68 matthew 612: </label>
613: </p><p>
614: <b>$lt{'irsp'}</b>
615: <label>
616: <input type="radio" name="showphotos" value="1" />$lt{'yes'}
617: </label>
618: <label>
619: <input type="radio" name="showphotos" value="0" checked="true" />$lt{'no'}
620: </label>
1.55 www 621: </p>
622: <hr />
623: <h2>$lt{'cc'}</h2>
624: <p>
1.68 matthew 625: <label>
626: <b>$lt{'user'}:</b> <input type="text" size="15" name="ccuname" />
627: </label>
628: </p><p>
629: <label>
630: <b>$lt{'dmn'}:</b> $domform
631: </label>
1.55 www 632: </p>
633: <p>
1.90 raeburn 634: <input type="hidden" name="prevphase" value="courseone" />
635: <input type="hidden" name="phase" value="coursetwo" />
1.68 matthew 636: <input type="button" onClick="verify_message(this.form)" value="$lt{'opco'}" />
1.10 matthew 637: </p>
1.2 www 638: </form>
639: ENDDOCUMENT
1.90 raeburn 640: } elsif ($crstype eq 'Group') {
641: $r->print(<<ENDDOCUMENT);
642: <form action="/adm/createcourse" method="post" name="ccrs">
643: <h2>$lt{'ginf'}</h2>
644: <p>
645: <label><b>$lt{'gtit'}:</b>
646: <input type="text" size="50" name="title" /></label>
647: </p><p>
648: <label>
649: <b>$lt{'ghsr'}:</b>$course_home
650: </label>
651: </p><p>
652: <label>
653: <b>$lt{'gidn'} ($lt{'opt'})</b>
654: <input type="text" size="30" name="crsid" />
655: </label>
656: </p>
657: <h2>$lt{'grco'}</h2>
658: <table border="2">
659: <tr><th>$lt{'cngr'}</th><th>$lt{'cegr'}</th></tr>
660: <tr><td>
661: <p>
662: <label>
663: <b>$lt{'map'}:</b>
664: <input type="text" size="50" name="topmap" />
665: </label>
666: <a href="javascript:openbrowser('ccrs','topmap')">$lt{'smap'}</a>
667: </p><p>
668: <label for="nonstd"><b>$lt{'sagr'}</b></label>
669: <br />
670: ($lt{'ocik'}):
671: <input id="nonstd" type="checkbox" name="nonstandard" />
672: </p><p>
673: <b>$lt{'fres'}</b><br />($lt{'stgo'}):
674: <label>
675: <input type="radio" name="firstres" value="blank" />$lt{'blnk'}
676: </label>
677:
678: <label>
679: <input type="radio" name="firstres" value="syl" checked />$lt{'sllb'}
680: </label>
681:
682: <label>
683: <input type="radio" name="firstres" value="nav" />$lt{'navi'}
684: </label>
685: </p>
686: </td><td>
687: <label>
688: $lt{'gid'}: <input type="text" size="25" name="clonecourse" value="" />
689: </label>
690: <br />
691: <label>
692: $lt{'dmn'}: $cloneform
693: </label>
694: <br />
695: <br />
696: $lt{'asov'}.
697: </td></tr>
698: </table>
699: </p>
700: <p>
701: <h2>$lt{'mssg'}</h2>
702: <p>
703: <label>
704: <b>$lt{'sgpf'}: </b>
705: <input type="checkbox" name="setpolicy" checked />
706: </label>
707: <br />
708: <label>
709: <b>$lt{'scfg'}: </b>
710: <input type="checkbox" name="setcontent" checked />
711: </label>
712: </p>
713: <h2>$lt{'cmmn'}</h2>
714: <p>
715: <label>
716: <b>$lt{'dmrd'}: </b>
717: <input type="checkbox" name="disresdis" />
718: </label>
719: <br />
720: <label>
721: <b>$lt{'dmuc'}: </b>
722: <input type="checkbox" name="disablechat" />
723: </label>
724: </p>
725: <h2>$lt{'acco'}</h2>
726: <p>
727: <label>
728: <b>$lt{'mnak'}: </b>
729: <input type="checkbox" name="setkeys" />
730: </label>
731: <br />
732: <label>
733: <b>$lt{'kaug'}: </b>
734: <input type="text" size="30" name="keyauth" />
735: </label>
736: </p>
737: <h2>$lt{'rshm'}</h2>
738: <p>
739: <label>
740: <b>$lt{'rshm'}: </b>
741: <input type="text" name="reshome" size="30" value="/res/$defdom/" />
742: </label>
743: </p>
744: <hr />
745: <h2>$lt{'gc'}</h2>
746: <p>
747: <label>
748: <b>$lt{'user'}:</b> <input type="text" size="15" name="ccuname" />
749: </label>
750: </p><p>
751: <label>
752: <b>$lt{'dmn'}:</b> $domform
753: </label>
754: </p>
755: <p>
756: <input type="hidden" name="prevphase" value="groupone" />
757: <input type="hidden" name="phase" value="grouptwo" />
758: <input type="button" onClick="validate(this.form)" value="$lt{'crgr'}" />
759: </p>
760: </form>
761: ENDDOCUMENT
762: }
763: $r->print($end_page);
1.40 raeburn 764: }
765:
1.2 www 766: # ====================================================== Phase two: make course
767:
1.10 matthew 768: sub create_course {
1.2 www 769: my $r=shift;
1.78 albertel 770: my $ccuname=$env{'form.ccuname'};
771: my $ccdomain=$env{'form.ccdomain'};
1.2 www 772: $ccuname=~s/\W//g;
773: $ccdomain=~s/\W//g;
1.90 raeburn 774: my $crstype = 'Group';
775: my ($enrollstart,$enrollend,$startaccess,$endaccess);
1.74 raeburn 776:
1.90 raeburn 777: if ($env{'form.phase'} eq 'coursetwo') {
778: $crstype='Course';
779: $enrollstart=&Apache::lonhtmlcommon::get_date_from_form('startenroll');
780: $enrollend=&Apache::lonhtmlcommon::get_date_from_form('endenroll');
781:
782: }
783: $startaccess = &Apache::lonhtmlcommon::get_date_from_form('startaccess');
784: $endaccess = &Apache::lonhtmlcommon::get_date_from_form('endaccess');
1.74 raeburn 785:
786: my $autharg;
787: my $authtype;
788:
1.78 albertel 789: if ($env{'form.login'} eq 'krb') {
1.74 raeburn 790: $authtype = 'krb';
1.78 albertel 791: $authtype .=$env{'form.krbver'};
792: $autharg = $env{'form.krbarg'};
793: } elsif ($env{'form.login'} eq 'int') {
1.74 raeburn 794: $authtype ='internal';
1.78 albertel 795: if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {
796: $autharg = $env{'form.intarg'};
1.74 raeburn 797: }
1.78 albertel 798: } elsif ($env{'form.login'} eq 'loc') {
1.74 raeburn 799: $authtype = 'localauth';
1.78 albertel 800: if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) {
801: $autharg = $env{'form.locarg'};
1.74 raeburn 802: }
803: }
1.90 raeburn 804: my $logmsg;
1.91 ! albertel 805: my $start_page=&Apache::loncommon::start_page('Create a New '.$crstype);
1.90 raeburn 806: my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('Creation Outcome','Create_Course',undef,'Create_Courses');
1.74 raeburn 807:
1.90 raeburn 808: $r->print($start_page.$crumbs);
1.74 raeburn 809:
810: my $args = {
1.90 raeburn 811: crstype => $crstype,
1.74 raeburn 812: ccuname => $ccuname,
813: ccdomain => $ccdomain,
1.78 albertel 814: cdescr => $env{'form.title'},
815: curl => $env{'form.topmap'},
816: course_domain => $env{'request.role.domain'},
817: course_home => $env{'form.course_home'},
818: nonstandard => $env{'form.nonstandard'},
819: crscode => $env{'form.crscode'},
820: clonecourse => $env{'form.clonecourse'},
821: clonedomain => $env{'form.clonedomain'},
822: crsid => $env{'form.crsid'},
823: curruser => $env{'user.name'},
824: crssections => $env{'form.crssections'},
825: crsxlist => $env{'form.crsxlist'},
826: autoadds => $env{'form.autoadds'},
827: autodrops => $env{'form.autodrops'},
828: notify_owner => $env{'form.notify_owner'},
829: notify_dc => $env{'form.notify_dc'},
830: no_end_date => $env{'form.no_end_date'},
831: showphotos => $env{'form.showphotos'},
1.74 raeburn 832: authtype => $authtype,
833: autharg => $autharg,
834: enrollstart => $enrollstart,
835: enrollend => $enrollend,
836: startaccess => $startaccess,
837: endaccess => $endaccess,
1.78 albertel 838: setpolicy => $env{'form.setpolicy'},
839: setcontent => $env{'form.setcontent'},
840: reshome => $env{'form.reshome'},
841: setkeys => $env{'form.setkeys'},
842: keyauth => $env{'form.keyauth'},
843: disresdis => $env{'form.disresdis'},
844: disablechat => $env{'form.disablechat'},
845: openall => $env{'form.openall'},
846: firstres => $env{'form.firstres'}
1.74 raeburn 847: };
848:
1.10 matthew 849: #
850: # Verify data
851: #
852: # Check the veracity of the course coordinator
1.2 www 853: if (&Apache::lonnet::homeserver($ccuname,$ccdomain) eq 'no_host') {
1.52 albertel 854: $r->print('<form action="/adm/createuser" method="post" name="crtuser">');
855: $r->print(&mt('No such user').' '.$ccuname.' '.&mt('at').' '.$ccdomain.'.<br />');
856: $r->print(&mt("Please click Back on your browser and select another user, or "));
857: $r->print('
858: <input type="hidden" name="phase" value="get_user_info" />
859: <input type="hidden" name="ccuname" value="'.$ccuname.'" />
860: <input type="hidden" name="ccdomain" value="'.$ccdomain.'" />
861: <input name="userrole" type="submit" value="'.
862: &mt('Create User').'" />
1.86 albertel 863: </form>'.&Apache::loncommon::end_page());
1.2 www 864: return;
865: }
1.10 matthew 866: # Check the proposed home server for the course
867: my %host_servers = &Apache::loncommon::get_library_servers
1.78 albertel 868: ($env{'request.role.domain'});
869: if (! exists($host_servers{$env{'form.course_home'}})) {
1.46 sakharuk 870: $r->print(&mt('Invalid home server for course').': '.
1.86 albertel 871: $env{'form.course_home'}.&Apache::loncommon::end_page());
1.10 matthew 872: return;
873: }
1.74 raeburn 874: my ($courseid,$crsudom,$crsunum);
1.78 albertel 875: $r->print(&construct_course($args,\$logmsg,\$courseid,\$crsudom,\$crsunum,$env{'user.domain'},$env{'user.name'}));
1.74 raeburn 876:
877: #
1.90 raeburn 878: # Make the requested user a course coordinator or group coordinator
1.74 raeburn 879: #
1.90 raeburn 880: if (($ccdomain) && ($ccuname)) {
881: $r->print(&mt('Assigning role of [_1] Coordinator to [_2] at [_3]:',
882: $crstype,$ccuname,$ccdomain).
883: &Apache::lonnet::assignrole($ccdomain,$ccuname,$courseid,
884: 'cc').'<p>');
885: }
1.78 albertel 886: if ($env{'form.setkeys'}) {
1.74 raeburn 887: $r->print(
888: '<p><a href="/adm/managekeys?cid='.$crsudom.'_'.$crsunum.'">'.&mt('Manage Access Keys').'</a></p>');
889: }
890: # Flush the course logs so reverse user roles immediately updated
891: &Apache::lonnet::flushcourselogs();
1.86 albertel 892: $r->print('<p>'.&mt('Roles will be active at next login').'.</p>'.
1.87 www 893: '<p><a href="/adm/createcourse">'.
1.90 raeburn 894: &mt('Create Another [_1]',$crstype).'</a></p>'.
1.86 albertel 895: &Apache::loncommon::end_page());
1.74 raeburn 896: }
897:
898: sub construct_course {
1.77 raeburn 899: my ($args,$logmsg,$courseid,$crsudom,$crsunum,$udom,$uname) = @_;
1.74 raeburn 900: my $outcome;
901:
1.2 www 902: #
903: # Open course
904: #
1.90 raeburn 905: my $crstype = lc($args->{'crstype'});
1.32 www 906: my %cenv=();
1.74 raeburn 907: $$courseid=&Apache::lonnet::createcourse($args->{'course_domain'},
908: $args->{'cdescr'},
909: $args->{'curl'},
910: $args->{'course_home'},
911: $args->{'nonstandard'},
912: $args->{'crscode'},
1.90 raeburn 913: $args->{'ccuname'},
914: $args->{'crstype'});
1.2 www 915:
1.27 bowersj2 916: # Note: The testing routines depend on this being output; see
917: # Utils::Course. This needs to at least be output as a comment
918: # if anyone ever decides to not show this, and Utils::Course::new
919: # will need to be suitably modified.
1.90 raeburn 920: $outcome .= &mt('New LON-CAPA [_1] ID: [_2]<br />',$crstype,$$courseid);
1.4 www 921: #
1.12 www 922: # Check if created correctly
1.4 www 923: #
1.74 raeburn 924: ($$crsudom,$$crsunum)=($$courseid=~/^\/(\w+)\/(\w+)$/);
925: my $crsuhome=&Apache::lonnet::homeserver($$crsunum,$$crsudom);
926: $outcome .= &mt('Created on').': '.$crsuhome.'<br>';
1.12 www 927: #
1.32 www 928: # Are we cloning?
929: #
930: my $cloneid='';
1.74 raeburn 931: if (($args->{'clonecourse'}) && ($args->{'clonedomain'})) {
932: $cloneid='/'.$args->{'clonedomain'}.'/'.$args->{'clonecourse'};
1.32 www 933: my ($clonecrsudom,$clonecrsunum)=($cloneid=~/^\/(\w+)\/(\w+)$/);
934: my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom);
935: if ($clonehome eq 'no_host') {
1.74 raeburn 936: $outcome .=
1.90 raeburn 937: '<br /><font color="red">'.&mt('Attempting to clone non-existing [_1]',$crstype).' '.$cloneid.'</font>';
1.32 www 938: } else {
1.74 raeburn 939: $outcome .=
1.90 raeburn 940: '<br /><font color="green">'.&mt('Cloning [_1] from [_2]',$crstype,$clonehome).'</font>';
1.74 raeburn 941: my %oldcenv=&Apache::lonnet::dump('environment',$$crsudom,$$crsunum);
1.32 www 942: # Copy all files
1.74 raeburn 943: ©coursefiles($cloneid,$$courseid);
1.37 www 944: # Restore URL
945: $cenv{'url'}=$oldcenv{'url'};
1.32 www 946: # Restore title
1.37 www 947: $cenv{'description'}=$oldcenv{'description'};
1.67 albertel 948: # restore grading mode
949: if (defined($oldcenv{'grading'})) {
950: $cenv{'grading'}=$oldcenv{'grading'};
951: }
1.37 www 952: # Mark as cloned
1.35 www 953: $cenv{'clonedfrom'}=$cloneid;
1.54 albertel 954: delete($cenv{'default_enrollment_start_date'});
955: delete($cenv{'default_enrollment_end_date'});
1.32 www 956: }
957: }
958: #
959: # Set environment (will override cloned, if existing)
1.12 www 960: #
1.64 raeburn 961: my @sections = ();
962: my @xlists = ();
1.90 raeburn 963: if ($args->{'crstype'}) {
964: $cenv{'type'}=$args->{'crstype'};
965: }
1.74 raeburn 966: if ($args->{'crsid'}) {
967: $cenv{'courseid'}=$args->{'crsid'};
1.40 raeburn 968: }
1.74 raeburn 969: if ($args->{'crscode'}) {
970: $cenv{'internal.coursecode'}=$args->{'crscode'};
1.40 raeburn 971: }
1.74 raeburn 972: if ($args->{'ccuname'}) {
973: $cenv{'internal.courseowner'} = $args->{'ccuname'};
1.64 raeburn 974: } else {
1.74 raeburn 975: $cenv{'internal.courseowner'} = $args->{'curruser'};
1.64 raeburn 976: }
977:
978: my @badclasses = (); # Used to accumulate sections/crosslistings that did not pass classlist access check for course owner.
1.74 raeburn 979: if ($args->{'crssections'}) {
1.64 raeburn 980: $cenv{'internal.sectionnums'} = '';
1.74 raeburn 981: if ($args->{'crssections'} =~ m/,/) {
982: @sections = split/,/,$args->{'crssections'};
1.44 raeburn 983: } else {
1.74 raeburn 984: $sections[0] = $args->{'crssections'};
1.44 raeburn 985: }
986: if (@sections > 0) {
1.64 raeburn 987: foreach my $item (@sections) {
988: my ($sec,$gp) = split/:/,$item;
1.74 raeburn 989: my $class = $args->{'crscode'}.$sec;
1.81 raeburn 990: my $addcheck = &Apache::lonnet::auto_new_course($$crsunum,$$crsudom,$class,$cenv{'internal.courseowner'});
1.73 raeburn 991: $cenv{'internal.sectionnums'} .= $item.',';
992: unless ($addcheck eq 'ok') {
1.64 raeburn 993: push @badclasses, $class;
994: }
1.44 raeburn 995: }
1.64 raeburn 996: $cenv{'internal.sectionnums'} =~ s/,$//;
1.44 raeburn 997: }
1.40 raeburn 998: }
1.49 www 999: # do not hide course coordinator from staff listing,
1000: # even if privileged
1.74 raeburn 1001: $cenv{'nothideprivileged'}=$args->{'ccuname'}.':'.$args->{'ccdomain'};
1002: # add crosslistings
1003: if ($args->{'crsxlist'}) {
1.64 raeburn 1004: $cenv{'internal.crosslistings'}='';
1.74 raeburn 1005: if ($args->{'crsxlist'} =~ m/,/) {
1006: @xlists = split/,/,$args->{'crsxlist'};
1.44 raeburn 1007: } else {
1.74 raeburn 1008: $xlists[0] = $args->{'crsxlist'};
1.44 raeburn 1009: }
1010: if (@xlists > 0) {
1.64 raeburn 1011: foreach my $item (@xlists) {
1012: my ($xl,$gp) = split/:/,$item;
1.74 raeburn 1013: my $addcheck = &Apache::lonnet::auto_new_course($$crsunum,$$crsudom,$xl,$cenv{'internal.courseowner'});
1.73 raeburn 1014: $cenv{'internal.crosslistings'} .= $item.',';
1015: unless ($addcheck eq 'ok') {
1.64 raeburn 1016: push @badclasses, $xl;
1017: }
1.44 raeburn 1018: }
1.64 raeburn 1019: $cenv{'internal.crosslistings'} =~ s/,$//;
1.44 raeburn 1020: }
1.40 raeburn 1021: }
1.74 raeburn 1022: if ($args->{'autoadds'}) {
1023: $cenv{'internal.autoadds'}=$args->{'autoadds'};
1.40 raeburn 1024: }
1.74 raeburn 1025: if ($args->{'autodrops'}) {
1026: $cenv{'internal.autodrops'}=$args->{'autodrops'};
1.40 raeburn 1027: }
1.77 raeburn 1028: # check for notification of enrollment changes
1029: my @notified = ();
1030: if ($args->{'notify_owner'}) {
1031: if ($args->{'ccuname'} ne '') {
1032: push(@notified,$args->{'ccuname'}.'@'.$args->{'ccdomain'});
1033: }
1034: }
1035: if ($args->{'notify_dc'}) {
1036: if ($uname ne '') {
1037: push(@notified,$uname.'@'.$udom);
1038: }
1039: }
1040: if (@notified > 0) {
1041: my $notifylist;
1042: if (@notified > 1) {
1043: $notifylist = join(',',@notified);
1044: } else {
1045: $notifylist = $notified[0];
1046: }
1047: $cenv{'internal.notifylist'} = $notifylist;
1.40 raeburn 1048: }
1.64 raeburn 1049: if (@badclasses > 0) {
1050: my %lt=&Apache::lonlocal::texthash(
1.73 raeburn 1051: 'tclb' => 'The courses listed below were included as sections or crosslistings affiliated with your new LON-CAPA course. However, if automated course roster updates are enabled for this class, these particular sections/crosslistings will not contribute towards enrollment, because the user identified as the course owner for this LON-CAPA course',
1.64 raeburn 1052: 'dnhr' => 'does not have rights to access enrollment in these classes',
1053: 'adby' => 'as determined by the policies of your institution on access to official classlists'
1054: );
1.74 raeburn 1055: $outcome .= '<font color="red">'.$lt{'tclb'}.' ('.$cenv{'internal.courseowner'}.') - '.$lt{'dnhr'}.' ('.$lt{'adby'}.').<br /><ul>'."\n";
1.64 raeburn 1056: foreach (@badclasses) {
1.74 raeburn 1057: $outcome .= "<li>$_</li>\n";
1.44 raeburn 1058: }
1.74 raeburn 1059: $outcome .= "</ul><br /><br /></font>\n";
1.40 raeburn 1060: }
1.74 raeburn 1061: if ($args->{'no_end_date'}) {
1062: $args->{'endaccess'} = 0;
1.40 raeburn 1063: }
1.74 raeburn 1064: $cenv{'internal.autostart'}=$args->{'enrollstart'};
1065: $cenv{'internal.autoend'}=$args->{'enrollend'};
1066: $cenv{'default_enrollment_start_date'}=$args->{'startaccess'};
1067: $cenv{'default_enrollment_end_date'}=$args->{'endaccess'};
1068: if ($args->{'showphotos'}) {
1069: $cenv{'internal.showphotos'}=$args->{'showphotos'};
1.40 raeburn 1070: }
1.74 raeburn 1071: $cenv{'internal.authtype'} = $args->{'authtype'};
1072: $cenv{'internal.autharg'} = $args->{'autharg'};
1.40 raeburn 1073: if ( ($cenv{'internal.authtype'} =~ /^krb/) && ($cenv{'internal.autoadds'} == 1)) {
1074: if (! defined($cenv{'internal.autharg'}) || $cenv{'internal.autharg'} eq '') {
1.74 raeburn 1075: $outcome .= '<font color="red" size="+1">'.
1076: &mt('As you did not include the default Kerberos domain to be used for authentication in this class, the institutional data used by the automated enrollment process must include the Kerberos domain for each new student').'</font></p>';
1.40 raeburn 1077: }
1.12 www 1078: }
1.74 raeburn 1079: if (($args->{'ccdomain'}) && ($args->{'ccuname'})) {
1080: if ($args->{'setpolicy'}) {
1081: $cenv{'policy.email'}=$args->{'ccuname'}.':'.$args->{'ccdomain'};
1.12 www 1082: }
1.74 raeburn 1083: if ($args->{'setcontent'}) {
1084: $cenv{'question.email'}=$args->{'ccuname'}.':'.$args->{'ccdomain'};
1.18 www 1085: }
1.55 www 1086: }
1.74 raeburn 1087: if ($args->{'reshome'}) {
1088: $cenv{'reshome'}=$args->{'reshome'}.'/';
1.55 www 1089: $cenv{'reshome'}=~s/\/+$/\//;
1.18 www 1090: }
1.56 www 1091: #
1092: # course has keyed access
1093: #
1.74 raeburn 1094: if ($args->{'setkeys'}) {
1.18 www 1095: $cenv{'keyaccess'}='yes';
1.16 www 1096: }
1.56 www 1097: # if specified, key authority is not course, but user
1098: # only active if keyaccess is yes
1.74 raeburn 1099: if ($args->{'keyauth'}) {
1100: $args->{'keyauth'}=~s/[^\w\@]//g;
1101: if ($args->{'keyauth'}) {
1102: $cenv{'keyauth'}=$args->{'keyauth'};
1.56 www 1103: }
1104: }
1105:
1.74 raeburn 1106: if ($args->{'disresdis'}) {
1.16 www 1107: $cenv{'pch.roles.denied'}='st';
1.26 matthew 1108: }
1.74 raeburn 1109: if ($args->{'disablechat'}) {
1.26 matthew 1110: $cenv{'plc.roles.denied'}='st';
1.21 albertel 1111: }
1.23 bowersj2 1112:
1.32 www 1113: # Record we've not yet viewed the Course Initialization Helper for this
1114: # course
1.23 bowersj2 1115: $cenv{'course.helper.not.run'} = 1;
1.21 albertel 1116: #
1117: # Use new Randomseed
1118: #
1.22 albertel 1119: $cenv{'rndseed'}=&Apache::lonnet::latest_rnd_algorithm_id();;
1.51 albertel 1120: $cenv{'receiptalg'}=&Apache::lonnet::latest_receipt_algorithm_id();;
1.53 www 1121: #
1122: # The encryption code and receipt prefix for this course
1123: #
1124: $cenv{'internal.encseed'}=$Apache::lonnet::perlvar{'lonReceipt'}.$$.time.int(rand(9999));
1125: $cenv{'internal.encpref'}=100+int(9*rand(99));
1.25 matthew 1126: #
1127: # By default, use standard grading
1.67 albertel 1128: if (!defined($cenv{'grading'})) { $cenv{'grading'} = 'standard'; }
1.22 albertel 1129:
1.74 raeburn 1130: $outcome .= ('<br />'.&mt('Setting environment').': '.
1131: &Apache::lonnet::put('environment',\%cenv,$$crsudom,$$crsunum).'<br>');
1.12 www 1132: #
1133: # Open all assignments
1134: #
1.74 raeburn 1135: if ($args->{'openall'}) {
1136: my $storeunder=$$crsudom.'_'.$$crsunum.'.0.opendate';
1.33 www 1137: my %storecontent = ($storeunder => time,
1138: $storeunder.'.type' => 'date_start');
1.12 www 1139:
1.74 raeburn 1140: $outcome .= &mt('Opening all assignments').': '.&Apache::lonnet::cput
1141: ('resourcedata',\%storecontent,$$crsudom,$$crsunum).'<br>';
1.12 www 1142: }
1.13 www 1143: #
1144: # Set first page
1145: #
1.74 raeburn 1146: unless (($args->{'nonstandard'}) || ($args->{'firstres'} eq 'blank')
1.48 www 1147: || ($cloneid)) {
1.74 raeburn 1148: $outcome .= &mt('Setting first resource').': ';
1.13 www 1149: my ($errtext,$fatal)=
1.74 raeburn 1150: &Apache::londocs::mapread($$crsunum,$$crsudom,'default.sequence');
1151: $outcome .= ($fatal?$errtext:'read ok').' - ';
1.13 www 1152: my $title; my $url;
1.74 raeburn 1153: if ($args->{'firstres'} eq 'syl') {
1.13 www 1154: $title='Syllabus';
1.74 raeburn 1155: $url='/public/'.$$crsudom.'/'.$$crsunum.'/syllabus';
1.13 www 1156: } else {
1157: $title='Navigate Contents';
1158: $url='/adm/navmaps';
1159: }
1160: $Apache::lonratedt::resources[1]=$title.':'.$url.':false:start:res';
1.15 albertel 1161: ($errtext,$fatal)=
1.74 raeburn 1162: &Apache::londocs::storemap($$crsunum,$$crsudom,'default.sequence');
1163: $outcome .= ($fatal?$errtext:'write ok').'<br>';
1.20 www 1164: }
1.74 raeburn 1165: return $outcome;
1.2 www 1166: }
1167:
1.90 raeburn 1168: sub print_intro_page {
1169: my $r = shift;
1170: my $start_page =
1171: &Apache::loncommon::start_page('Create a New Course or Group Space');
1172: my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('Creation Options','Create_Course',undef,'Create_Courses');
1173: my $end_page =
1174: &Apache::loncommon::end_page();
1175: my $helplink=&Apache::loncommon::help_open_topic('Create_Course_GroupSpace',&mt('Help on Creating Courses and Groups'));
1176:
1177: my @choices = ({ internal_name => 'courseone',
1178: name => &mt('Create a single course'),
1179: short_description =>
1180: &mt('Create a new course by completing an online form.'),
1181: },
1182: { internal_name => 'groupone',
1183: name => &mt('Create a single collaborative group space '),
1184: short_description =>
1185: &mt('Create a new group space for non-course use by completing an online form .'),
1186: },
1187: { internal_name => 'batchone',
1188: name => &mt('Create courses/groups by uploading an attributes file'),
1189: short_description =>
1190: &mt('Upload an attributes file containing specifications for one or more courses or groups in XML format'),
1191: },
1192: );
1193: my $options;
1194: foreach my $choice (@choices) {
1195: $options .=' <h3><a href="/adm/createcourse?phase='.
1196: $choice->{'internal_name'}.'" >'.
1197: $choice->{'name'}."</a></h3>\n";
1198: $options .= ' '.(' 'x8).$choice->{'short_description'}.
1199: "\n";
1200: }
1201:
1202: $r->print(<<ENDDOCUMENT);
1203: $start_page
1204: $crumbs
1205: $options
1206: $end_page
1207: ENDDOCUMENT
1208: }
1209:
1210: sub upload_batchfile {
1211: my $r = shift;
1212: my $start_page =
1213: &Apache::loncommon::start_page('Create a New Course or Group Space');
1214: my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('Upload Course/Group Attributes File','Create_Course',undef,'Create_Courses');
1215: my $end_page =
1216: &Apache::loncommon::end_page();
1217: $r->print($start_page.$crumbs);
1218: $r->print('<h3>'.&mt('Upload a courses or groups attributes file').'</h3>');
1219: $r->print('<form name="batchcreate" method="post" '.
1220: 'enctype="multipart/form-data" action="/adm/createcourse">'.
1221: '<input type="file" name="coursecreatorxml" />'.
1222: '<input type="hidden" name="phase" value="batchtwo"><br /><br />'.
1223: '<input type="submit" name="batchsubmit" '.
1224: 'value="Create Courses/Groups" /></form>');
1225: $r->print($end_page);
1226: return;
1227: }
1228:
1229: sub process_batchfile {
1230: my $r = shift;
1231: my $start_page =
1232: &Apache::loncommon::start_page('Create a New Course or Group Space');
1233: my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('Creation Outcome','Create_Course',undef,'Create_Courses');
1234: my $end_page =
1235: &Apache::loncommon::end_page();
1236: my $defdom=$env{'request.role.domain'};
1237: my $batchfilepath=&Apache::lonnet::userfileupload('coursecreatorxml',undef,
1238: 'batchupload',undef,undef,
1239: undef,undef,$defdom);
1240: my ($batchdir,$filename) = ($batchfilepath =~ m-^(.+)/pending/([^/]+)$-);
1241: my ($result,$logmsg);
1242: if (-e "$batchfilepath") {
1243: open(FILE,"<$batchfilepath");
1244: my @buffer = <FILE>;
1245: close(FILE);
1246: if ((defined($filename)) && (defined($batchdir))) {
1247: my @requests = ($filename);
1248: my %courseids = ();
1249: ($result,$logmsg) = &LONCAPA::batchcreatecourse::create_courses(
1250: \@requests,\%courseids,'web',$defdom,
1251: $env{'user.name'},$env{'user.domain'});
1252: if ($result) {
1253: if (!-e "$batchdir/processed") {
1254: mkdir("$batchdir/processed", 0755);
1255: open(FILE,">$batchdir/processed/$filename");
1256: print FILE @buffer;
1257: close(FILE);
1258: if (-e "$batchdir/processed/$filename") {
1259: unlink("$batchdir/pending/$filename");
1260: }
1261: }
1262: }
1263: }
1264: }
1265: $r->print($start_page.$crumbs.$result.$end_page);
1266:
1267: }
1268:
1.2 www 1269: # ===================================================================== Handler
1.1 www 1270: sub handler {
1271: my $r = shift;
1272:
1273: if ($r->header_only) {
1.38 www 1274: &Apache::loncommon::content_type($r,'text/html');
1.1 www 1275: $r->send_http_header;
1276: return OK;
1277: }
1278:
1.78 albertel 1279: if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) {
1.38 www 1280: &Apache::loncommon::content_type($r,'text/html');
1.1 www 1281: $r->send_http_header;
1282:
1.90 raeburn 1283: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1284: ['phase']);
1285: &Apache::lonhtmlcommon::clear_breadcrumbs();
1286: &Apache::lonhtmlcommon::add_breadcrumb
1287: ({href=>"/adm/createcourse",
1288: text=>"Creation Options",
1289: faq=>79,bug=>'Dom Coord Interface',});
1290: if (($env{'form.phase'} eq 'coursetwo') ||
1291: ($env{'form.phase'} eq 'grouptwo')) {
1292: &Apache::lonhtmlcommon::add_breadcrumb
1293: ({href=>"/adm/createcourse?phase=$env{'form.prevphase'}",
1294: text=>&mt('[_1] Creation Settings',),
1295: faq=>9,bug=>'Dom Coord Interface',});
1296: &Apache::lonhtmlcommon::add_breadcrumb
1297: ({href=>"/adm/createcourse?phase=$env{'form.phase'}",
1298: text=>"Creation Outcome",
1299: faq=>9,bug=>'Dom Coord Interface',});
1.10 matthew 1300: &create_course($r);
1.90 raeburn 1301: } elsif (($env{'form.phase'} eq 'courseone') ||
1302: ($env{'form.phase'} eq 'groupone')) {
1303: &Apache::lonhtmlcommon::add_breadcrumb
1304: ({href=>"/adm/createcourse?phase=$env{'form.phase'}",
1305: text=>&mt('[_1] Creation Settings',),
1306: faq=>9,bug=>'Dom Coord Interface',});
1307: &print_course_creation_page($r);
1308: } elsif ($env{'form.phase'} eq 'batchone') {
1309: &Apache::lonhtmlcommon::add_breadcrumb
1310: ({href=>"/adm/createcourse?phase=$env{'form.phase'}",
1311: text=>"Upload Description File",
1312: faq=>9,bug=>'Dom Coord Interface',});
1313: &upload_batchfile($r);
1314: } elsif ($env{'form.phase'} eq 'batchtwo') {
1315: &Apache::lonhtmlcommon::add_breadcrumb
1316: ({href=>"/adm/createcourse?phase=$env{'form.prevphase'}",
1317: text=>"Upload Description File",
1318: faq=>9,bug=>'Dom Coord Interface',});
1319: &Apache::lonhtmlcommon::add_breadcrumb
1320: ({href=>"/adm/createcourse?phase=$env{'form.phase'}",
1321: text=>"Creation Outcome",
1322: faq=>9,bug=>'Dom Coord Interface',});
1323: &process_batchfile($r);
1.2 www 1324: } else {
1.90 raeburn 1325: &print_intro_page($r);
1.2 www 1326: }
1.1 www 1327: } else {
1.78 albertel 1328: $env{'user.error.msg'}=
1.90 raeburn 1329: "/adm/createcourse:ccc:0:0:Cannot create courses or groups";
1.1 www 1330: return HTTP_NOT_ACCEPTABLE;
1331: }
1332: return OK;
1.90 raeburn 1333: }
1.1 www 1334:
1335: 1;
1336: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>