Annotation of loncom/interface/loncreatecourse.pm, revision 1.47
1.1 www 1: # The LearningOnline Network
2: # Create a course
1.5 albertel 3: #
1.47 ! www 4: # $Id: loncreatecourse.pm,v 1.46 2003/12/11 17:31:23 sakharuk 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.1 www 28: # (My Desk
29: #
30: # (Internal Server Error Handler
31: #
32: # (Login Screen
33: # 5/21/99,5/22,5/25,5/26,5/31,6/2,6/10,7/12,7/14,
34: # 1/14/00,5/29,5/30,6/1,6/29,7/1,11/9 Gerd Kortemeyer)
35: #
36: # 3/1/1 Gerd Kortemeyer)
37: #
38: # 3/1 Gerd Kortemeyer)
39: #
1.4 www 40: # 2/14,2/16,2/17,7/6 Gerd Kortemeyer
1.1 www 41: #
42: package Apache::loncreatecourse;
43:
44: use strict;
45: use Apache::Constants qw(:common :http);
46: use Apache::lonnet;
1.12 www 47: use Apache::loncommon;
1.13 www 48: use Apache::lonratedt;
49: use Apache::londocs;
1.38 www 50: use Apache::lonlocal;
1.41 raeburn 51: use Apache::londropadd;
1.44 raeburn 52: use lib '/home/httpd/lib/perl';
53: use localenroll;
1.28 www 54:
55: # ================================================ Get course directory listing
56:
57: sub crsdirlist {
58: my ($courseid,$which)=@_;
59: unless ($which) { $which=''; }
60: my %crsdata=&Apache::lonnet::coursedescription($courseid);
61: my @listing=&Apache::lonnet::dirlist
62: ($which,$crsdata{'domain'},$crsdata{'num'},
1.39 albertel 63: &Apache::loncommon::propath($crsdata{'domain'},$crsdata{'num'}));
1.28 www 64: my @output=();
65: foreach (@listing) {
66: unless ($_=~/^\./) {
67: push (@output,(split(/\&/,$_))[0]);
68: }
69: }
70: return @output;
1.29 www 71: }
72:
73: # ============================================================= Read a userfile
74:
75: sub readfile {
76: my ($courseid,$which)=@_;
77: my %crsdata=&Apache::lonnet::coursedescription($courseid);
78: return &Apache::lonnet::getfile('/uploaded/'.$crsdata{'domain'}.'/'.
79: $crsdata{'num'}.'/'.$which);
80: }
81:
82: # ============================================================ Write a userfile
83:
84: sub writefile {
1.30 www 85: (my $courseid, my $which,$ENV{'form.output'})=@_;
1.29 www 86: my %crsdata=&Apache::lonnet::coursedescription($courseid);
87: return &Apache::lonnet::finishuserfileupload(
88: $crsdata{'num'},$crsdata{'domain'},
89: $crsdata{'home'},
90: 'output',$which);
91: }
92:
1.36 www 93: # ===================================================================== Rewrite
94:
95: sub rewritefile {
96: my ($contents,%rewritehash)=@_;
97: foreach (keys %rewritehash) {
98: my $pattern=$_;
99: $pattern=~s/(\W)/\\$1/gs;
100: my $new=$rewritehash{$_};
101: $contents=~s/$pattern/$new/gs;
102: }
103: return $contents;
104: }
105:
1.29 www 106: # ============================================================= Copy a userfile
107:
108: sub copyfile {
109: my ($origcrsid,$newcrsid,$which)=@_;
1.36 www 110: unless ($which=~/\.sequence$/) {
111: return &writefile($newcrsid,$which,
112: &readfile($origcrsid,$which));
113: } else {
114: my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
115: my %newcrsdata= &Apache::lonnet::coursedescription($newcrsid);
116: return &writefile($newcrsid,$which,
117: &rewritefile(
118: &readfile($origcrsid,$which),
119: (
120: '/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'
121: => '/uploaded/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/'
122: )));
123: }
1.30 www 124: }
125:
126: # =============================================================== Copy a dbfile
127:
128: sub copydb {
129: my ($origcrsid,$newcrsid,$which)=@_;
130: $which=~s/\.db$//;
131: my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
132: my %newcrsdata= &Apache::lonnet::coursedescription($newcrsid);
133: my %data=&Apache::lonnet::dump
134: ($which,$origcrsdata{'domain'},$origcrsdata{'num'});
135: return &Apache::lonnet::put
136: ($which,\%data,$newcrsdata{'domain'},$newcrsdata{'num'});
137: }
138:
1.35 www 139: # ========================================================== Copy resourcesdata
140:
141: sub copyresourcedb {
142: my ($origcrsid,$newcrsid)=@_;
143: my %origcrsdata=&Apache::lonnet::coursedescription($origcrsid);
144: my %newcrsdata= &Apache::lonnet::coursedescription($newcrsid);
145: my %data=&Apache::lonnet::dump
146: ('resourcedata',$origcrsdata{'domain'},$origcrsdata{'num'});
147: $origcrsid=~s/^\///;
148: $origcrsid=~s/\//\_/;
149: $newcrsid=~s/^\///;
150: $newcrsid=~s/\//\_/;
151: my %newdata=();
152: undef %newdata;
153: my $startdate=$data{$origcrsid.'.0.opendate'};
154: my $today=time;
155: my $delta=0;
156: if ($startdate) {
157: my $oneday=60*60*24;
158: $delta=$today-$startdate;
159: $delta=int($delta/$oneday)*$oneday;
160: }
161: # ugly retro fix for broken version of types
162: foreach (keys %data) {
163: if ($_=~/\wtype$/) {
164: my $newkey=$_;
165: $newkey=~s/type$/\.type/;
166: $data{$newkey}=$data{$_};
167: delete $data{$_};
168: }
169: }
1.37 www 170: # adjust symbs
171: my $pattern='uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/';
172: $pattern=~s/(\W)/\\$1/gs;
173: my $new= 'uploaded/'. $newcrsdata{'domain'}.'/'. $newcrsdata{'num'}.'/';
174: foreach (keys %data) {
175: if ($_=~/$pattern/) {
176: my $newkey=$_;
177: $newkey=~s/$pattern/$new/;
178: $data{$newkey}=$data{$_};
179: delete $data{$_};
180: }
181: }
1.35 www 182: # adjust dates
183: foreach (keys %data) {
184: my $thiskey=$_;
185: $thiskey=~s/^$origcrsid/$newcrsid/;
186: $newdata{$thiskey}=$data{$_};
187: if ($data{$_.'.type'}=~/^date/) {
188: $newdata{$thiskey}=$newdata{$thiskey}+$delta;
189: }
190: }
191: return &Apache::lonnet::put
192: ('resourcedata',\%newdata,$newcrsdata{'domain'},$newcrsdata{'num'});
193: }
194:
1.30 www 195: # ========================================================== Copy all userfiles
196:
197: sub copyuserfiles {
198: my ($origcrsid,$newcrsid)=@_;
199: foreach (&crsdirlist($origcrsid,'userfiles')) {
200: ©file($origcrsid,$newcrsid,$_);
201: }
202: }
203: # ========================================================== Copy all userfiles
204:
205: sub copydbfiles {
206: my ($origcrsid,$newcrsid)=@_;
207: foreach (&crsdirlist($origcrsid)) {
208: if ($_=~/\.db$/) {
209: unless
1.34 www 210: ($_=~/^(nohist\_|discussiontimes|classlist|versionupdate|resourcedata)/) {
1.30 www 211: ©db($origcrsid,$newcrsid,$_);
212: }
213: }
214: }
1.31 www 215: }
216:
217: # ======================================================= Copy all course files
218:
219: sub copycoursefiles {
220: my ($origcrsid,$newcrsid)=@_;
221: ©userfiles($origcrsid,$newcrsid);
222: ©dbfiles($origcrsid,$newcrsid);
1.35 www 223: ©resourcedb($origcrsid,$newcrsid);
1.28 www 224: }
1.13 www 225:
1.2 www 226: # ===================================================== Phase one: fill-in form
227:
1.10 matthew 228: sub print_course_creation_page {
1.2 www 229: my $r=shift;
1.10 matthew 230: my $defdom=$ENV{'request.role.domain'};
231: my %host_servers = &Apache::loncommon::get_library_servers($defdom);
232: my $course_home = '<select name="course_home" size="1">'."\n";
233: foreach my $server (sort(keys(%host_servers))) {
1.14 matthew 234: $course_home .= qq{<option value="$server"};
235: if ($server eq $Apache::lonnet::perlvar{'lonHostID'}) {
236: $course_home .= " selected ";
237: }
238: $course_home .= qq{>$server $host_servers{$server}</option>};
1.10 matthew 239: }
240: $course_home .= "\n</select>\n";
1.9 matthew 241: my $domform = &Apache::loncommon::select_dom_form($defdom,'ccdomain');
1.12 www 242: my $bodytag=&Apache::loncommon::bodytag('Create a New Course');
1.46 sakharuk 243: my $helplink=&Apache::loncommon::help_open_topic('Create_Course',&mt('Help on Creating Courses'));
1.32 www 244: my $cloneform=&Apache::loncommon::select_dom_form
245: ($ENV{'request.role.domain'},'clonedomain').
246: &Apache::loncommon::selectcourse_link
247: ('ccrs','clonecourse','clonedomain');
248: my $coursebrowserjs=&Apache::loncommon::coursebrowser_javascript();
1.43 raeburn 249: my $starttime = time;
250: my $endtime = time+(6*30*24*60*60); # 6 months from now, approx
251: my $date_table = &Apache::londropadd::date_setting_table($starttime,$endtime,'createcourse');
1.40 raeburn 252: my ($krbdef,$krbdefdom) =
253: &Apache::loncommon::get_kerberos_defaults($defdom);
1.41 raeburn 254: my $javascript_validations=&Apache::londropadd::javascript_validations('createcourse',$krbdefdom);
1.40 raeburn 255: my %param = ( formname => 'document.ccrs',
256: kerb_def_dom => $krbdefdom,
257: kerb_def_auth => $krbdef
258: );
259: my $krbform = &Apache::loncommon::authform_kerberos(%param);
260: my $intform = &Apache::loncommon::authform_internal(%param);
261: my $locform = &Apache::loncommon::authform_local(%param);
1.46 sakharuk 262: my %lt=&Apache::lonlocal::texthash(
263: 'cinf' => "Course Information",
264: 'ctit' => "Course Title",
265: 'chsr' => "Course Home Server",
266: 'cidn' => "Course ID/Number",
267: 'opt' => "optional",
268: 'iinf' => "Institutional Information",
269: '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.",
270: 'ccod' => "Course Code",
271: 'toin' => "to interface with institutional data, e.g., fs03glg231 for Fall 2003 Geology 231",
272: 'snid' => "Section Numbers and corresponding LON-CAPA section/group IDs",
273: 'csli' => "a comma separated list of institutional section numbers, each separated by a colon from the (optional) corresponding section/group ID to be used in LON-CAPA e.g., 001:1,002:2",
274: 'crcs' => "Crosslisted courses",
275: '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) groupID to be used in LON-CAPA, e.g., fs03ent231001:ent1,fs03bot231001:bot1,fs03zol231002:bot2",
276: 'crco' => "Course Content",
277: 'cncr' => "Completely new course",
278: 'cecr' => "Clone an existing course",
279: 'map' => "Map",
280: 'smap' => "Select Map",
281: 'sacr' => "Do NOT generate as standard course",
282: 'ocik' => "only check if you know what you are doing",
283: 'fres' => "First Resource",
284: 'stco' => "standard courses only",
285: 'blnk' => "Blank",
286: 'sllb' => "Syllabus",
287: 'navi' => "Navigate",
288: 'cid' => "Course ID",
289: 'dmn' => "Domain",
290: 'asov' => "Additional settings, if specified below, will override cloned settings",
291: 'assp' => "Assessment Parameters",
292: 'oaas' => "Open all assessments",
293: 'mssg' => "Messaging",
294: 'scpf' => "Set course policy feedback to Course Coordinator",
295: 'scfc' => "Set content feedback to Course Coordinator",
296: 'cmmn' => "Communication",
297: 'dsrd' => "Disable student resource discussion",
298: 'dsuc' => "Disable student use of chatrooms",
299: 'acco' => "Access Control",
300: 'snak' => "Students need access key to enter course",
301: 'cc' => "Course Coordinator",
302: 'user' => "Username",
303: 'ierc' => "Immediately expire own role as Course Coordinator",
304: 'aens' => "Automated enrollment settings",
305: '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.",
306: 'aadd' => "Automated adds",
307: 'yes' => "Yes",
308: 'no' => "No",
309: 'audr' => "Automated drops",
310: 'dacu' => "Duration of automated classlist updates",
311: 'psam' => "Please select the authentication mechanism",
312: 'pcda' => "Please choose the default authentication method to be used by new users added to this LON-CAPA domain by the automated enrollment process",
313: 'nech' => "Notification of enrollment changes",
314: 'nccl' => "Notification to course coordinator via LON-CAPA message when enrollment changes occur during the automated update?",
315: 'irsp' => "Include retrieval of student photographs?",
316: 'opco' => "Open Course"
317: );
1.2 www 318: $r->print(<<ENDDOCUMENT);
319: <html>
1.6 matthew 320: <script language="JavaScript" type="text/javascript">
321: var editbrowser = null;
322: function openbrowser(formname,elementname) {
323: var url = '/res/?';
324: if (editbrowser == null) {
325: url += 'launch=1&';
326: }
327: url += 'catalogmode=interactive&';
328: url += 'mode=edit&';
329: url += 'form=' + formname + '&';
1.7 matthew 330: url += 'element=' + elementname + '&';
331: url += 'only=sequence' + '';
1.6 matthew 332: var title = 'Browser';
333: var options = 'scrollbars=1,resizable=1,menubar=0';
334: options += ',width=700,height=600';
335: editbrowser = open(url,title,options,'1');
336: editbrowser.focus();
337: }
1.41 raeburn 338: $javascript_validations
1.6 matthew 339: </script>
1.32 www 340: $coursebrowserjs
1.2 www 341: <head>
342: <title>The LearningOnline Network with CAPA</title>
343: </head>
1.12 www 344: $bodytag
1.17 www 345: $helplink
1.6 matthew 346: <form action="/adm/createcourse" method="post" name="ccrs">
1.46 sakharuk 347: <h2>$lt{'cinf'}</h2>
1.10 matthew 348: <p>
1.46 sakharuk 349: <b>$lt{'ctit'}:</b>
1.6 matthew 350: <input type="text" size="50" name="title">
1.10 matthew 351: </p><p>
1.46 sakharuk 352: <b>$lt{'chsr'}:</b>$course_home
1.13 www 353: </p><p>
1.46 sakharuk 354: <b>$lt{'cidn'} ($lt{'opt'})</b>
1.13 www 355: <input type="text" size="30" name="crsid">
1.40 raeburn 356: </p><p>
1.46 sakharuk 357: <h2>$lt{'iinf'}</h2>
1.40 raeburn 358: <p>
1.46 sakharuk 359: $lt{'stat'}
1.40 raeburn 360: </p><p>
1.46 sakharuk 361: <b>$lt{'ccod'}</b>
1.40 raeburn 362: <input type="text" size="30" name="crscode" /><br/>
1.46 sakharuk 363: ($lt{'toin'})
1.40 raeburn 364: </p><p>
1.46 sakharuk 365: <b>$lt{'snid'}</b>
1.40 raeburn 366: <input type="text" size="30" name="crssections" /><br/>
1.46 sakharuk 367: ($lt{'csli'})
1.40 raeburn 368: </p><p>
1.46 sakharuk 369: <b>$lt{'crcs'}</b>
1.40 raeburn 370: <input type="text" size="30" name="crsxlist" /><br/>
1.46 sakharuk 371: ($lt{'cscs'})
1.13 www 372: </p>
1.46 sakharuk 373: <h2>$lt{'crco'}</h2>
1.32 www 374: <table border="2">
1.46 sakharuk 375: <tr><th>$lt{'cncr'}</th><th>$lt{'cecr'}</th></tr>
1.32 www 376: <tr><td>
1.13 www 377: <p>
1.46 sakharuk 378: <b>$lt{'map'}:</b>
1.6 matthew 379: <input type="text" size="50" name="topmap">
1.46 sakharuk 380: <a href="javascript:openbrowser('ccrs','topmap')">$lt{'smap'}</a>
1.10 matthew 381: </p><p>
1.46 sakharuk 382: <b>$lt{'sacr'}</b><br />
383: ($lt{'ocik'}):
1.11 www 384: <input type="checkbox" name="nonstandard">
1.13 www 385: </p>
386: <p>
1.46 sakharuk 387: <b>$lt{'fres'}</b><br />($lt{'stco'}):
388: <input type="radio" name="firstres" value="blank">$lt{'blnk'}
1.13 www 389:
1.46 sakharuk 390: <input type="radio" name="firstres" value="syl" checked>$lt{'sllb'}
1.13 www 391:
1.46 sakharuk 392: <input type="radio" name="firstres" value="nav">$lt{'navi'}
1.13 www 393: </p>
1.32 www 394: </td><td>
1.46 sakharuk 395: $lt{'cid'}: <input input type="text" size="25" name="clonecourse" value="" />
1.32 www 396: <br />
1.46 sakharuk 397: $lt{'dmn'}:
1.32 www 398: $cloneform<br /> <br />
1.46 sakharuk 399: $lt{'asov'}.
1.32 www 400: </td></tr>
401: </table>
1.46 sakharuk 402: <h2>$lt{'assp'}</h2>
1.13 www 403: <p>
1.46 sakharuk 404: <b>$lt{'oaas'}: </b>
1.11 www 405: <input type="checkbox" name="openall" checked>
1.13 www 406: </p>
1.46 sakharuk 407: <h2>$lt{'mssg'}</h2>
1.13 www 408: <p>
1.46 sakharuk 409: <b>$lt{'scpf'}: </b>
1.11 www 410: <input type="checkbox" name="setpolicy" checked>
411: </p><p>
1.46 sakharuk 412: <b>$lt{'scfc'}: </b>
1.11 www 413: <input type="checkbox" name="setcontent" checked>
414: </p>
1.46 sakharuk 415: <h2>$lt{'cmmn'}</h2>
1.16 www 416: <p>
1.46 sakharuk 417: <b>$lt{'dsrd'}: </b>
1.26 matthew 418: <input type="checkbox" name="disresdis" /> <br />
1.46 sakharuk 419: <b>$lt{'dsuc'}: </b>
1.26 matthew 420: <input type="checkbox" name="disablechat" />
1.16 www 421: </p>
1.46 sakharuk 422: <h2>$lt{'acco'}</h2>
1.18 www 423: <p>
1.46 sakharuk 424: <b>$lt{'snak'}: </b>
1.18 www 425: <input type="checkbox" name="setkeys" />
426: </p>
1.46 sakharuk 427: <h2>$lt{'cc'}</h2>
1.10 matthew 428: <p>
1.46 sakharuk 429: <b>$lt{'user'}:</b> <input type="text" size="15" name="ccuname" />
1.11 www 430: </p><p>
1.46 sakharuk 431: <b>$lt{'dmn'}:</b> $domform
1.10 matthew 432: </p><p>
1.46 sakharuk 433: <b>$lt{'ierc'}:</b>
1.11 www 434: <input type="checkbox" name="expireown" checked>
1.10 matthew 435: </p><p>
1.46 sakharuk 436: <h2>$lt{'aens'}</h2>
437: $lt{'aesc'}
1.40 raeburn 438: </p>
439: <p>
1.46 sakharuk 440: <b>$lt{'aadd'}</b>
441: <input type="radio" name="autoadds" value="1" />$lt{'yes'} <input type="radio" name="autoadds" value="0" checked="true" />$lt{'no'}
1.40 raeburn 442: </p><p>
1.46 sakharuk 443: <b>$lt{'audr'}</b>
444: <input type="radio" name="autodrops" value="1" />$lt{'yes'} <input type="radio" name="autodrops" value="0" checked="true" />$lt{'no'}
1.40 raeburn 445: </p><p>
1.46 sakharuk 446: <b>$lt{'dacu'}</b>
1.40 raeburn 447: $date_table
448: </p><p>
1.46 sakharuk 449: <b>$lt{'psam'}.</b><br />
450: $lt{'pcda'}.
1.40 raeburn 451: </p><p>
452: $krbform
453: <br />
454: $intform
455: <br />
456: $locform
457: </p><p>
1.46 sakharuk 458: <b>$lt{'nech'}</b><br />
459: $lt{'nccl'}<br/>
460: <input type="radio" name="notify" value="1" />$lt{'yes'} <input type="radio" name="notify"
461: value="0" checked="true" />$lt{'no'}
1.40 raeburn 462: </p><p>
1.46 sakharuk 463: <b>$lt{'irsp'}</b> <input type="radio" name="showphotos" value="1" />$lt{'yes'} <input type="radio" name="showphotos" value="0" checked="true" />$lt{'no'}
1.40 raeburn 464: </p><p>
1.10 matthew 465: <input type="hidden" name="phase" value="two" />
1.46 sakharuk 466: <input type="button" onClick="verify_message(this.form)" value="$lt{'opco'}">
1.10 matthew 467: </p>
1.2 www 468: </form>
469: </body>
470: </html>
471: ENDDOCUMENT
1.40 raeburn 472: }
473:
1.2 www 474: # ====================================================== Phase two: make course
475:
1.10 matthew 476: sub create_course {
1.2 www 477: my $r=shift;
478: my $topurl='/res/'.&Apache::lonnet::declutter($ENV{'form.topmap'});
479: my $ccuname=$ENV{'form.ccuname'};
480: my $ccdomain=$ENV{'form.ccdomain'};
481: $ccuname=~s/\W//g;
482: $ccdomain=~s/\W//g;
483: my $cdescr=$ENV{'form.title'};
484: my $curl=$ENV{'form.topmap'};
1.12 www 485: my $bodytag=&Apache::loncommon::bodytag('Create a New Course');
1.2 www 486: $r->print(<<ENDENHEAD);
487: <html>
488: <head>
489: <title>The LearningOnline Network with CAPA</title>
490: </head>
1.12 www 491: $bodytag
1.2 www 492: ENDENHEAD
1.10 matthew 493: #
494: # Verify data
495: #
496: # Check the veracity of the course coordinator
1.2 www 497: if (&Apache::lonnet::homeserver($ccuname,$ccdomain) eq 'no_host') {
1.46 sakharuk 498: $r->print(&mt('No such user').' '.$ccuname.' '.&mt('at').' '.$ccdomain.'</body></html>');
1.2 www 499: return;
500: }
1.10 matthew 501: # Check the proposed home server for the course
502: my %host_servers = &Apache::loncommon::get_library_servers
503: ($ENV{'request.role.domain'});
504: if (! exists($host_servers{$ENV{'form.course_home'}})) {
1.46 sakharuk 505: $r->print(&mt('Invalid home server for course').': '.
1.10 matthew 506: $ENV{'form.course_home'}.'</body></html>');
507: return;
508: }
1.2 www 509: #
510: # Open course
511: #
1.32 www 512: my %cenv=();
1.10 matthew 513: my $courseid=&Apache::lonnet::createcourse($ENV{'request.role.domain'},
514: $cdescr,$curl,
1.11 www 515: $ENV{'form.course_home'},
516: $ENV{'form.nonstandard'});
1.2 www 517:
1.27 bowersj2 518: # Note: The testing routines depend on this being output; see
519: # Utils::Course. This needs to at least be output as a comment
520: # if anyone ever decides to not show this, and Utils::Course::new
521: # will need to be suitably modified.
1.4 www 522: $r->print('New LON-CAPA Course ID: '.$courseid.'<br>');
523: #
1.12 www 524: # Check if created correctly
1.4 www 525: #
526: my ($crsudom,$crsunum)=($courseid=~/^\/(\w+)\/(\w+)$/);
527: my $crsuhome=&Apache::lonnet::homeserver($crsunum,$crsudom);
1.46 sakharuk 528: $r->print(&mt('Created on').': '.$crsuhome.'<br>');
1.12 www 529: #
1.32 www 530: # Are we cloning?
531: #
532: my $cloneid='';
533: if (($ENV{'form.clonecourse'}) && ($ENV{'form.clonedomain'})) {
534: $cloneid='/'.$ENV{'form.clonedomain'}.'/'.$ENV{'form.clonecourse'};
535: my ($clonecrsudom,$clonecrsunum)=($cloneid=~/^\/(\w+)\/(\w+)$/);
536: my $clonehome=&Apache::lonnet::homeserver($clonecrsunum,$clonecrsudom);
537: if ($clonehome eq 'no_host') {
538: $r->print(
1.46 sakharuk 539: '<br /><font color="red">'.&mt('Attempting to clone non-existing course').' '.$cloneid.'</font>');
1.32 www 540: } else {
541: $r->print(
1.46 sakharuk 542: '<br /><font color="green">'.&mt('Cloning course from').' '.$clonehome.'</font>');
1.37 www 543: my %oldcenv=&Apache::lonnet::dump('environment',$crsudom,$crsunum);
1.32 www 544: # Copy all files
545: ©coursefiles($cloneid,$courseid);
1.37 www 546: # Restore URL
547: $cenv{'url'}=$oldcenv{'url'};
1.32 www 548: # Restore title
1.37 www 549: $cenv{'description'}=$oldcenv{'description'};
550: # Mark as cloned
1.35 www 551: $cenv{'clonedfrom'}=$cloneid;
1.32 www 552: }
553: }
554: #
555: # Set environment (will override cloned, if existing)
1.12 www 556: #
1.44 raeburn 557: my @affiliates = (); # Used to accumulate sections and crosslistings
1.4 www 558: if ($ENV{'form.crsid'}) {
1.12 www 559: $cenv{'courseid'}=$ENV{'form.crsid'};
1.40 raeburn 560: }
561: if ($ENV{'form.crscode'}) {
562: $cenv{'internal.coursecode'}=$ENV{'form.crscode'};
563: }
564: if ($ENV{'form.crssections'}) {
565: $cenv{'internal.sectionnums'}=$ENV{'form.crssections'};
1.44 raeburn 566: my @sections = ();
567: if ($cenv{'internal.sectionnums'} =~ m/,/) {
568: @sections = split/,/,$cenv{'internal.sectionnums'};
569: } else {
570: $sections[0] = $cenv{'internal.sectionnums'};
571: }
572: if (@sections > 0) {
573: foreach (@sections) {
574: my ($sec,$gp) = split/:/,$_;
575: push @affiliates,$ENV{'form.crscode'}.$sec;
576: }
577: }
1.40 raeburn 578: }
579: if ($ENV{'form.crsxlist'}) {
1.44 raeburn 580: $cenv{'internal.crosslistings'}=$ENV{'form.crsxlist'};
581: my @xlists = ();
582: if ($cenv{'internal.crosslistings'} =~ m/,/) {
583: @xlists = split/,/,$cenv{'internal.crosslistings'};
584: } else {
585: $xlists[0] = $cenv{'internal.crosslistings'};
586: }
587: if (@xlists > 0) {
588: foreach (@xlists) {
589: my ($xl,$gp) = split/:/,$_;
590: push @affiliates,$xl;
591: }
592: }
1.40 raeburn 593: }
594: if ($ENV{'form.autoadds'}) {
595: $cenv{'internal.autoadds'}=$ENV{'form.autoadds'};
596: }
597: if ($ENV{'form.autodrops'}) {
598: $cenv{'internal.autodrops'}=$ENV{'form.autodrops'};
599: }
600: if ($ENV{'form.notify'}) {
601: if ($ccuname) {
602: $cenv{'internal.notifylist'} = $ccuname;
603: }
604: }
605: if ($ccuname) {
606: $cenv{'internal.courseowner'} = $ccuname;
1.44 raeburn 607: } else {
608: $cenv{'internal.courseowner'} = $ENV{'user.name'};
609: }
610: if (@affiliates > 0) {
611: my @badclasses = ();
612: foreach my $class (@affiliates) {
613: my $addcheck = &localenroll::new_course($class,$cenv{'internal.courseowner'});
614: unless ($addcheck eq 'ok') {
615: push @badclasses, $class;
616: }
617: }
618: if (@badclasses > 0) {
619: $r->print('<font color="red">'.
620: "The courses listed below were included as sections or crosslistings affiliated with your new LON-CAPA course. 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 ($cenv{'internal.courseowner'}) - does not have rights to access enrollment in these classes (as determined by your instititution's policies on access to official classlists).<br/><ul>\n");
621: foreach (@badclasses) {
622: $r->print("<li>$_</li>\n");
623: }
624: $r->print ("</ul><br/><br/></font>\n");
625: }
1.40 raeburn 626: }
627: my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
628: my $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate');
629: if ($ENV{'form.no_end_date'}) {
630: $enddate = 0;
631: }
632: $cenv{'internal.autostart'}=$startdate;
633: $cenv{'internal.autoend'}=$enddate;
634: if ($ENV{'form.showphotos'}) {
635: $cenv{'internal.showphotos'}=$ENV{'form.showphotos'};
636: }
637: if ($ENV{'form.login'} eq 'krb') {
638: $cenv{'internal.authtype'} = 'krb';
639: $cenv{'internal.authtype'} .=$ENV{'form.krbver'};
640: $cenv{'internal.autharg'} = $ENV{'form.krbarg'};
641: } elsif ($ENV{'form.login'} eq 'int') {
642: $cenv{'internal.authtype'} ='internal';
643: if ((defined($ENV{'form.intarg'})) && ($ENV{'form.intarg'})) {
644: $cenv{'internal.autharg'} = $ENV{'form.intarg'};
645: }
646: } elsif ($ENV{'form.login'} eq 'loc') {
647: $cenv{'internal.authtype'} = 'localauth';
648: if ((defined($ENV{'form.locarg'})) && ($ENV{'form.locarg'})) {
649: $cenv{'internal.autharg'} = $ENV{'form.locarg'};
650: }
651: }
652: if ( ($cenv{'internal.authtype'} =~ /^krb/) && ($cenv{'internal.autoadds'} == 1)) {
653: if (! defined($cenv{'internal.autharg'}) || $cenv{'internal.autharg'} eq '') {
654: $r->print('<font color="red" size="+1">'.
1.46 sakharuk 655: &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 656: }
1.12 www 657: }
658: if (($ccdomain) && ($ccuname)) {
659: if ($ENV{'form.setpolicy'}) {
660: $cenv{'policy.email'}=$ccuname.':'.$ccdomain;
661: }
662: if ($ENV{'form.setcontent'}) {
1.18 www 663: $cenv{'question.email'}=$ccuname.':'.$ccdomain;
664: }
665: }
666: if ($ENV{'form.setkeys'}) {
667: $cenv{'keyaccess'}='yes';
1.16 www 668: }
669: if ($ENV{'form.disresdis'}) {
670: $cenv{'pch.roles.denied'}='st';
1.26 matthew 671: }
672: if ($ENV{'form.disablechat'}) {
673: $cenv{'plc.roles.denied'}='st';
1.21 albertel 674: }
1.23 bowersj2 675:
1.32 www 676: # Record we've not yet viewed the Course Initialization Helper for this
677: # course
1.23 bowersj2 678: $cenv{'course.helper.not.run'} = 1;
1.21 albertel 679: #
680: # Use new Randomseed
681: #
1.22 albertel 682: $cenv{'rndseed'}=&Apache::lonnet::latest_rnd_algorithm_id();;
1.25 matthew 683: #
684: # By default, use standard grading
685: $cenv{'grading'} = 'standard';
1.22 albertel 686:
1.46 sakharuk 687: $r->print('<br />'.&mt('Setting environment').': '.
1.12 www 688: &Apache::lonnet::put('environment',\%cenv,$crsudom,$crsunum).'<br>');
689: #
690: # Open all assignments
691: #
692: if ($ENV{'form.openall'}) {
693: my $storeunder=$crsudom.'_'.$crsunum.'.0.opendate';
1.33 www 694: my %storecontent = ($storeunder => time,
695: $storeunder.'.type' => 'date_start');
1.12 www 696:
1.46 sakharuk 697: $r->print(&mt('Opening all assignments').': '.&Apache::lonnet::cput
1.12 www 698: ('resourcedata',\%storecontent,$crsudom,$crsunum).'<br>');
699: }
1.13 www 700: #
701: # Set first page
702: #
703: unless (($ENV{'form.nonstandard'}) || ($ENV{'form.firstres'} eq 'blank')) {
1.46 sakharuk 704: $r->print(&mt('Setting first resource').': ');
1.13 www 705: my ($errtext,$fatal)=
706: &Apache::londocs::mapread($crsunum,$crsudom,'default.sequence');
707: $r->print(($fatal?$errtext:'read ok').' - ');
708: my $title; my $url;
709: if ($ENV{'form.firstres'} eq 'syl') {
710: $title='Syllabus';
711: $url='/public/'.$crsudom.'/'.$crsunum.'/syllabus';
712: } else {
713: $title='Navigate Contents';
714: $url='/adm/navmaps';
715: }
716: $Apache::lonratedt::resources[1]=$title.':'.$url.':false:start:res';
1.15 albertel 717: ($errtext,$fatal)=
1.13 www 718: &Apache::londocs::storemap($crsunum,$crsudom,'default.sequence');
719: $r->print(($fatal?$errtext:'write ok').'<br>');
720: }
1.2 www 721: #
722: # Make current user course adminstrator
723: #
1.12 www 724: my $end=undef;
725: my $addition='';
726: if ($ENV{'form.expireown'}) { $end=time+5; $addition='expired'; }
1.46 sakharuk 727: $r->print(&mt('Assigning').' '.$addition.' '.&mt('role of course coordinator to self').': '.
1.2 www 728: &Apache::lonnet::assignrole(
1.12 www 729: $ENV{'user.domain'},$ENV{'user.name'},$courseid,'cc',$end).'<br>');
1.2 www 730: #
731: # Make additional user course administrator
732: #
1.12 www 733: if (($ccdomain) && ($ccuname)) {
1.46 sakharuk 734: $r->print(&mt('Assigning role of course coordinator to').' '.
1.2 www 735: $ccuname.' at '.$ccdomain.': '.
1.3 www 736: &Apache::lonnet::assignrole($ccdomain,$ccuname,$courseid,'cc').'<p>');
1.12 www 737: }
1.20 www 738: if ($ENV{'form.setkeys'}) {
739: $r->print(
1.46 sakharuk 740: '<p><a href="/adm/managekeys?cid='.$crsudom.'_'.$crsunum.'">'.&mt('Manage Access Keys').'</a></p>');
1.20 www 741: }
1.47 ! www 742: # Flush the course logs so reverse user roles immediately updated
! 743: &Apache::lonnet::flushcourselogs();
1.46 sakharuk 744: $r->print('<p>'.&mt('Roles will be active at next login').'.</p></body></html>');
1.2 www 745: }
746:
747: # ===================================================================== Handler
1.1 www 748: sub handler {
749: my $r = shift;
750:
751: if ($r->header_only) {
1.38 www 752: &Apache::loncommon::content_type($r,'text/html');
1.1 www 753: $r->send_http_header;
754: return OK;
755: }
756:
1.10 matthew 757: if (&Apache::lonnet::allowed('ccc',$ENV{'request.role.domain'})) {
1.38 www 758: &Apache::loncommon::content_type($r,'text/html');
1.1 www 759: $r->send_http_header;
760:
1.2 www 761: if ($ENV{'form.phase'} eq 'two') {
1.10 matthew 762: &create_course($r);
1.2 www 763: } else {
1.10 matthew 764: &print_course_creation_page($r);
1.2 www 765: }
1.1 www 766: } else {
767: $ENV{'user.error.msg'}=
768: "/adm/createcourse:ccc:0:0:Cannot create courses";
769: return HTTP_NOT_ACCEPTABLE;
770: }
771: return OK;
772: }
773:
774: 1;
775: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>