Annotation of loncom/interface/coursecatalog.pm, revision 1.34
1.17 albertel 1: # The LearningOnline Network with CAPA
2: # Handler for displaying the course catalog interface
3: #
1.34 ! raeburn 4: # $Id: coursecatalog.pm,v 1.33 2008/06/30 04:07:06 raeburn Exp $
1.1 raeburn 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28:
29: package Apache::coursecatalog;
30:
31: use strict;
32: use lib qw(/home/httpd/lib/perl);
33: use Apache::Constants qw(:common);
34: use Apache::loncommon;
1.7 raeburn 35: use Apache::lonhtmlcommon;
1.1 raeburn 36: use Apache::lonnet;
37: use Apache::lonlocal;
1.6 raeburn 38: use Apache::courseclassifier;
1.1 raeburn 39: use Apache::lonacc;
40: use LONCAPA;
41:
42: sub handler {
43: my ($r) = @_;
44: &Apache::loncommon::content_type($r,'text/html');
45: $r->send_http_header;
46: if ($r->header_only) {
47: return OK;
48: }
1.21 albertel 49: my $handle = &Apache::lonnet::check_for_valid_session($r);
1.8 raeburn 50: my $lonidsdir=$r->dir_config('lonIDsDir');
1.21 albertel 51: if ($handle ne '') {
1.8 raeburn 52: &Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle);
53: }
1.1 raeburn 54: &Apache::lonacc::get_posted_cgi($r);
55: &Apache::lonlocal::get_language_handle($r);
56: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['sortby']);
1.28 raeburn 57:
58: my $codedom = &Apache::lonnet::default_login_domain();
1.19 raeburn 59:
60: if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne 'public')) {
61: $codedom = $env{'user.domain'};
62: if ($env{'request.role.domain'} ne '') {
63: $codedom = $env{'request.role.domain'};
64: }
65: }
1.7 raeburn 66: my $formname = 'coursecatalog';
1.28 raeburn 67: if ($env{'form.showdom'} ne '') {
68: if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') {
69: $codedom = $env{'form.showdom'};
70: }
71: }
1.20 albertel 72: my $domdesc = &Apache::lonnet::domain($codedom,'description');
1.7 raeburn 73: &Apache::lonhtmlcommon::clear_breadcrumbs();
1.8 raeburn 74: if ($env{'form.coursenum'} ne '' && &user_is_known()) {
1.7 raeburn 75: &course_details($r,$codedom,$formname,$domdesc);
76: } else {
1.28 raeburn 77: my $catlinks = &category_breadcrumbs($codedom);
78: my $catjs = <<"ENDSCRIPT";
79:
80: function setCatDepth(depth) {
81: document.coursecats.catalog_maxdepth.value = depth;
82: document.coursecats.submit();
83: return;
84: }
85:
86: ENDSCRIPT
1.33 raeburn 87: if ($env{'form.state'} eq 'listing') {
88: $catjs .= qq|
89: function changeSort(caller) {
90: document.$formname.sortby.value = caller;
91: document.$formname.submit();
92: }
93: function setCourseId(caller) {
94: document.$formname.coursenum.value = caller;
95: document.$formname.submit();
96: }\n|;
97: }
1.28 raeburn 98: my $numtitles;
99: if ($env{'form.currcat_0'} eq 'instcode::0') {
100: $numtitles = &instcode_course_selector($r,$codedom,$formname,$domdesc,
101: $catlinks,$catjs);
102: if ($env{'form.state'} eq 'listing') {
103: $r->print(&print_course_listing($codedom,$numtitles));
104: }
105: } else {
106: my (%add_entries);
107: $catjs = '<script type="text/javascript">'."\n".$catjs."\n".'</script>';
108: &cat_header($r,$codedom,$catjs,\%add_entries,$catlinks);
109: if ($env{'form.currcat_0'} ne '') {
1.33 raeburn 110: $r->print('<form name="'.$formname.
111: '" method="post" action="/adm/coursecatalog">'.
112: &additional_filters($codedom)."\n");
113: my ($currdepth,$deeper) = &get_depth_values();
114: $r->print('<input type="hidden" name="catalog_maxdepth" value="'.
115: $deeper.'" />'."\n");
116: for (my $i=0; $i<$deeper; $i++) {
117: $r->print('<input type="hidden" name="currcat_'.$i.'" value="'.$env{'form.currcat_'.$i}.'" />'."\n");
118: }
119: $r->print('<input type="hidden" name="coursenum" value="" />'."\n".
120: '<input type="hidden" name="sortby" value="" />'."\n".
121: '<input type="hidden" name="state" value="listing" />'."\n".
122: '<input type="hidden" name="showdom" value="'.
123: $env{'form.showdom'}.'" />'.
124: '<input type="submit" name="catalogfilter" value="'.
125: &mt('Display courses').'" /></form><br /><br />');
126: }
127: if ($env{'form.state'} eq 'listing') {
1.28 raeburn 128: $r->print(&print_course_listing($codedom));
129: }
1.18 raeburn 130: }
1.7 raeburn 131: }
1.32 raeburn 132: $r->print('<br />'.&Apache::loncommon::end_page());
1.7 raeburn 133: return OK;
134: }
135:
136: sub course_details {
137: my ($r,$codedom,$formname,$domdesc) = @_;
138: my $output;
139: my %add_entries = (topmargin => "0",
140: marginheight => "0",);
141: my $start_page =
142: &Apache::loncommon::start_page('Course Catalog','',
143: {
144: 'add_entries' => \%add_entries,
145: 'no_inline_link' => 1,});
146: $r->print($start_page);
1.19 raeburn 147: if ($env{'form.numtitles'} > 0) {
148: &Apache::lonhtmlcommon::add_breadcrumb
149: ({href=>"/adm/coursecatalog",
150: text=>"Select courses"});
151: }
1.7 raeburn 152: &Apache::lonhtmlcommon::add_breadcrumb
1.19 raeburn 153: ({href=>"javascript:document.$formname.submit()",
1.7 raeburn 154: text=>"Course listing"},
155: {text=>"Course details"});
156: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Details'));
157: $r->print('<br />'.&mt('Detailed course information:').'<br /><br />'.
1.28 raeburn 158: '<form name="'.$formname.'" method="post">'.
1.7 raeburn 159: &print_course_listing($codedom).'<br /><br />');
160: $r->print('<a href = "javascript:document.coursecatalog.submit()">'.
161: &mt('Back to course listing').'</a>'.
162: '<input type="hidden" name="sortby" value="'.
163: $env{'form.sortby'}.'" />'.
164: '<input type="hidden" name="state" value="listing" /></form>');
165: }
166:
1.28 raeburn 167: sub instcode_course_selector {
168: my ($r,$codedom,$formname,$domdesc,$catlinks,$catjs) = @_;
1.1 raeburn 169: my %coursecodes = ();
170: my %codes = ();
171: my @codetitles = ();
172: my %cat_titles = ();
173: my %cat_order = ();
174: my %idlist = ();
175: my %idnums = ();
176: my %idlist_titles = ();
1.6 raeburn 177: my %by_year;
178: my %by_sem;
179: my %by_dept;
180: my %cat_items;
1.1 raeburn 181: my $caller = 'global';
182: my $format_reply;
183: my $totcodes = 0;
184: my $jscript = '';
1.6 raeburn 185: my ($numtitles,$lasttitle);
1.30 raeburn 186: my %add_entries = (topmargin => "0",
187: marginheight => "0",);
188: my $js;
1.22 raeburn 189: $totcodes = &Apache::courseclassifier::retrieve_instcodes(\%coursecodes,$codedom);
1.1 raeburn 190: if ($totcodes > 0) {
1.6 raeburn 191: $format_reply = &Apache::lonnet::auto_instcode_format($caller,$codedom,\%coursecodes,\%codes,\@codetitles,\%cat_titles,\%cat_order);
192: if ($format_reply eq 'ok') {
193: my $numtypes = @codetitles;
194: &Apache::courseclassifier::build_code_selections(\%codes,\@codetitles,\%cat_titles,\%cat_order,\%idlist,\%idnums,\%idlist_titles);
195: my ($scripttext,$longtitles) = &Apache::courseclassifier::javascript_definitions(\@codetitles,\%idlist,\%idlist_titles,\%idnums,\%cat_titles);
196: my $longtitles_str = join('","',@{$longtitles});
197: my $allidlist = $idlist{$codetitles[0]};
198: $numtitles = @codetitles;
199: $lasttitle = $numtitles;
200: if ($numtitles > 4) {
201: $lasttitle = 4;
1.1 raeburn 202: }
1.18 raeburn 203: if ($numtitles == 0) {
204: if (!defined($env{'form.state'})) {
205: $env{'form.state'} = 'listing';
206: }
207: } else {
208: my @data = ('top');
209: for (my $k=0; $k<$lasttitle; $k++) {
210: my $cat = $codetitles[$k];
211: my $level = 1;
212: $level = &recurse_options($codetitles[$k],$idlist{$codetitles[$k]},$level,$cat,\%cat_items,\@data,\%by_year,\%by_sem,\%by_dept);
213: }
214: $scripttext .= &build_javascript(\%by_year,\%by_sem,\%by_dept,\%cat_order,\@codetitles);
215: $jscript .= &javascript_select_filler($formname,$scripttext,\@codetitles,$longtitles_str,$allidlist);
216: if ($env{'form.state'} eq 'listing') {
217: $jscript .= '
1.1 raeburn 218: function setElements() {
219: ';
1.18 raeburn 220: for (my $i=0; $i<@codetitles-1; $i++) {
221: if ($env{'form.'.$codetitles[$i]} != -1) {
222: $jscript .= '
1.1 raeburn 223: for (var j=0; j<document.'.$formname.'.'.$codetitles[$i].'.length; j++) {
224: if (document.'.$formname.'.'.$codetitles[$i].'[j].value == "'.$env{'form.'.$codetitles[$i]}.'") {
225: document.'.$formname.'.'.$codetitles[$i].'.selectedIndex = j;
226: }
227: }
228: ';
1.18 raeburn 229: }
230: }
231: $jscript .= ' courseSet()'."\n";
232: if ($env{'form.'.$codetitles[-1]} != -1) {
233: $jscript .= '
1.6 raeburn 234: for (var j=0; j<document.'.$formname.'.'.$codetitles[-1].'.length; j++) {
235: if (document.'.$formname.'.'.$codetitles[-1].'[j].value == "'.$env{'form.'.$codetitles[-1]}.'") {
236: document.'.$formname.'.'.$codetitles[-1].'.selectedIndex = j;
237: }
238: }
239: ';
1.18 raeburn 240: }
241: $jscript .= '}';
242: }
1.6 raeburn 243: }
1.32 raeburn 244: }
1.30 raeburn 245: $js = '<script type"text/javascript">'."\n$jscript\n$catjs\n".
246: '</script>';
1.18 raeburn 247: if (($env{'form.state'} eq 'listing') && ($numtitles > 0)) {
1.7 raeburn 248: $add_entries{'onLoad'} = 'setElements()';
249: }
1.28 raeburn 250: &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles);
251: my $cat_maxdepth = $env{'form.catalog_maxdepth'};
252: $r->print('<form name="'.$formname.'" method="post" action="/adm/coursecatalog">'.
1.32 raeburn 253: '<input type="hidden" name="catalog_maxdepth" value="'.$cat_maxdepth.'" />'."\n".
254: '<input type="hidden" name="showdom" value="'.$env{'form.showdom'}.'" />'."\n".
255: '<input type="hidden" name="currcat_0" value="instcode::0" />'.
1.33 raeburn 256: &additional_filters($codedom));
1.1 raeburn 257: if ($numtitles > 0) {
1.32 raeburn 258: $r->print('<b>'.&mt('Choose which course(s) to list.').'</b><br />');
1.6 raeburn 259: $r->print('<table><tr>');
260: for (my $k=0; $k<$lasttitle-1; $k++) {
1.26 raeburn 261: my (@items,@unsorted);
262: if (ref($cat_items{$codetitles[$k]}) eq 'ARRAY') {
263: @unsorted = @{$cat_items{$codetitles[$k]}};
264: }
1.6 raeburn 265: &Apache::courseclassifier::sort_cats($k,\%cat_order,\@codetitles,\@unsorted,\@items);
266: my @longitems;
267: if (defined($cat_titles{$codetitles[$k]})) {
268: foreach my $item (@items) {
269: push(@longitems,$cat_titles{$codetitles[$k]}{$item});
270: }
1.1 raeburn 271: } else {
1.6 raeburn 272: @longitems = @items;
1.1 raeburn 273: }
1.6 raeburn 274: $r->print('<td align="center">'.$codetitles[$k].'<br />'."\n".
275: '<select name="'.$codetitles[$k].'" onChange="courseSet()"');
276: $r->print('>'."\n".'<option value="0" />All'."\n");
277: for (my $i=0; $i<@items; $i++) {
1.1 raeburn 278: if ($longitems[$i] eq '') {
279: $longitems[$i] = $items[$i];
280: }
1.6 raeburn 281: $r->print(' <option value="'.$items[$i].'">'.$longitems[$i].'</option>');
1.1 raeburn 282: }
1.6 raeburn 283: $r->print('</select></td>');
1.1 raeburn 284: }
1.6 raeburn 285: $r->print('<td align="center">'.$codetitles[$lasttitle-1].'<br />'."\n".
286: '<select name="'.$codetitles[$lasttitle-1].'">'."\n".
287: '<option value="0">All'."\n".
288: '</option>'."\n".'</select>'."\n".
1.32 raeburn 289: '</td></tr></table>'."\n");
1.1 raeburn 290: if ($numtitles > 4) {
1.6 raeburn 291: $r->print('<br /><br />'.$codetitles[$numtitles-1].'<br />'."\n".
292: '<input type="text" name="'.$codetitles[$numtitles-1].'" /><br />'."\n");
1.1 raeburn 293: }
1.18 raeburn 294: $r->print('<br />');
295: }
1.33 raeburn 296: $r->print('<input type="hidden" name="coursenum" value="" />'."\n".
297: '<input type="hidden" name="sortby" value="" />'."\n".
298: '<input type="hidden" name="state" value="listing" />'."\n".
299: '<input type="hidden" name="form.currcat_0" value="instcode::0" />'."\n".
300: '<input type="submit" name="catalogfilter" value="'.
301: &mt('Display courses').'" />'.
302: '<input type="hidden" name="numtitles" value="'.$numtitles.
303: '" /></form>');
1.18 raeburn 304: if (($numtitles > 0) && ($env{'form.state'} eq 'listing')) {
1.28 raeburn 305: $r->print('<br />');
1.1 raeburn 306: }
1.5 raeburn 307: } else {
1.30 raeburn 308: &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles);
309: my $cat_maxdepth = $env{'form.catalog_maxdepth'};
310: $r->print('<form name="'.$formname.'" method="post" action="/adm/coursecatalog">'.
311: '<input type="hidden" name="catalog_maxdepth" value="'.$cat_maxdepth.'" />'.
312: '<input type="hidden" name="showdom" value="'.$env{'form.showdom'}.'" />'.
313: '<input type="hidden" name="currcat_0" value="instcode::0" />');
314: $r->print('<br />'.&mt('No official courses to display for [_1].',$domdesc).'</form>');
1.1 raeburn 315: }
1.18 raeburn 316: return $numtitles;
1.1 raeburn 317: }
318:
1.28 raeburn 319: sub cat_header {
320: my ($r,$codedom,$js,$add_entries,$catlinks,$numtitles) = @_;
321: my $start_page =
322: &Apache::loncommon::start_page('Course Catalog',$js,
323: {
324: 'add_entries' => $add_entries,
325: 'no_inline_link' => 1,});
326: $r->print($start_page);
327: if ($env{'form.state'} eq 'listing') {
328: if ($numtitles > 0) {
329: &Apache::lonhtmlcommon::add_breadcrumb
330: ({href=>"/adm/coursecatalog",
331: text=>"Select courses"},
332: {text=>"Course listing"});
333: } else {
334: &Apache::lonhtmlcommon::add_breadcrumb
335: ({text=>"Course listing"});
336: }
337: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course Listing'));
338: } else {
339: &Apache::lonhtmlcommon::add_breadcrumb
340: ({href=>"/adm/coursecatalog",
341: text=>"Select courses"});
342: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Select courses'));
343: }
1.34 ! raeburn 344: $r->print('<form name="coursecatdom" method="post" action="/adm/coursecatalog">'.
! 345: '<table border="0"><tr><td><b>'.&mt('Domain:').'</b></td><td>'.
1.28 raeburn 346: &Apache::loncommon::select_dom_form($codedom,'showdom','',1).
1.34 ! raeburn 347: ' <input type="submit" name="godom" value="'.&mt('Change').'" /></td></tr></table></form>'.
! 348: '<form name="coursecats" method="post" action="/adm/coursecatalog">'.
! 349: '<table border="0"><tr>'.$catlinks.'</tr></table></form>');
1.28 raeburn 350: return;
351: }
352:
353: sub category_breadcrumbs {
354: my ($dom) = @_;
355: my %domconfig =
356: &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom);
1.32 raeburn 357: my (@cats,@trails,%allitems,%idx,@jsarray,$cathash);
358: if (ref($domconfig{'coursecategories'}) eq 'HASH') {
359: $cathash = $domconfig{'coursecategories'}{'cats'};
360: } else {
361: $cathash = {};
362: }
363: &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,\%allitems,\%idx,
364: \@jsarray);
1.33 raeburn 365: my ($currdepth,$deeper) = &get_depth_values();
366: my $currcat_str = '<input type="hidden" name="catalog_maxdepth" value="'.$deeper.'" /><input type="hidden" name="showdom" value="'.$dom.'" />';
1.28 raeburn 367: my $catlinks = '<td valign="top"><b>'.&mt('Catalog:').'</b></td><td><table><tr>';
368: for (my $i=0; $i<$deeper; $i++) {
369: $currcat_str .= '<input type="hidden" name="currcat_'.$i.'" value="'.$env{'form.currcat_'.$i}.'" />';
370: my ($cattitle,$shallower);
371: if ($i == 0) {
372: $cattitle = &mt('Main Categories');
373: } else {
374: $shallower = $i-1;
375: my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$env{'form.currcat_'.$shallower});
376: $cattitle = $cat;
377: }
378: $catlinks .= '<td valign="top"><a href="javascript:setCatDepth('."'$shallower'".')">'.$cattitle.'</a>-></td>';
379: }
380: if ($deeper == 0) {
381: $catlinks .= '<td>'.&mt('Main Categories').': ';
382: if (ref($cats[0]) eq 'ARRAY') {
383: if ((@{$cats[0]} == 1) && ($cats[0][0] eq 'instcode')) {
384: $catlinks .= &mt('Official courses (with institutional codes)').
1.34 ! raeburn 385: '<input type="hidden" name="currcat_0" value="instcode::0" />';
1.28 raeburn 386: $env{'form.currcat_0'} = 'instcode::0';
387: } else {
388: $catlinks .= '<select name="currcat_0">'."\n";
389: if (@{$cats[0]} > 1) {
390: my $selstr;
391: if ($env{'form.currcat_0'} eq '') {
392: $selstr = ' selected="selected" ';
393: }
394: $catlinks .= '<option value=""'.$selstr.'>'.&mt('Select').'</option>'."\n";
395: }
396: for (my $i=0; $i<@{$cats[0]}; $i++) {
397: my $name = $cats[0][$i];
398: my $item = &escape($name).'::0';
399: my $selstr;
400: if ($env{'form.currcat_'.$i} eq $item) {
401: $selstr = ' selected="selected" ';
402: }
403: $catlinks .= '<option value="'.$item.'"'.$selstr.'>';
404: if ($name eq 'instcode') {
405: $catlinks .= &mt('Official courses (with institutional codes)');
406: } else {
407: $catlinks .= $name;
408: }
409: $catlinks .= '</option>'."\n";
410: }
411: $catlinks .= '</select>'."\n".
1.33 raeburn 412: ' <input type="submit" name="gocats" value="'.&mt('Change').'" />';
1.28 raeburn 413: }
414: } else {
415: $catlinks .= &mt('Official courses (with institutional codes)').
1.34 ! raeburn 416: '<input type="hidden" name="currcat_0" value="instcode::0" />';
1.28 raeburn 417: $env{'form.currcat_0'} = 'instcode::0';
418: }
419: } else {
1.29 raeburn 420: my ($cat,$container,$depth);
421: if ($env{'form.currcat_'.$currdepth} eq '') {
422: my $shallower = $currdepth - 1;
423: ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$env{'form.currcat_'.$shallower});
424: } else {
425: ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$env{'form.currcat_'.$currdepth});
426: }
1.28 raeburn 427: my $deeper = $depth +1;
428: my $currcat = $cat;
429: if ($cat eq 'instcode') {
430: $currcat = &mt('Official courses (with institutional codes)');
431: }
432: $catlinks .= '<td>'.$currcat;
433: if (ref($cats[$deeper]{$cat}) eq 'ARRAY') {
434: $catlinks .= ': <select name="currcat_'.$deeper.'">'.
435: '<option value="" selected="selected">'.&mt('Select').'</option>';
436: for (my $k=0; $k<@{$cats[$deeper]{$cat}}; $k++) {
437: my $name = $cats[$deeper]{$cat}[$k];
438: my $item = &escape($name).':'.&escape($cat).':'.$deeper;
439: $catlinks .= '<option value="'.$item.'">'.$name.'</option>'."\n";
440: }
441: $catlinks .= '</select>'."\n".
1.33 raeburn 442: ' <input type="submit" name="gocats" value="'.&mt('Change').'" />';
1.28 raeburn 443: }
444: }
445: $catlinks .= $currcat_str.'</td></tr></table></td>';
446: return $catlinks;
447: }
448:
1.33 raeburn 449: sub get_depth_values {
450: my $currdepth = 0;
451: my $deeper = 0;
452: if ($env{'form.catalog_maxdepth'} ne '') {
453: $currdepth = $env{'form.catalog_maxdepth'};
454: if ($env{'form.currcat_'.$currdepth} eq '') {
455: $deeper = $currdepth;
456: } else {
457: $deeper = $currdepth + 1;
458: }
459: }
460: return ($currdepth,$deeper);
461: }
462:
463: sub additional_filters {
464: my ($codedom) = @_;
465: my $output = '<table>';
466: my $show_selfenroll_status;
467: if ($env{'form.showselfenroll'}) {
468: $show_selfenroll_status = 'checked="checked" ';
469: }
470: if (&user_is_dc($codedom)) {
471: my $showdetails_status;
472: if ($env{'form.showdetails'}) {
473: $showdetails_status = 'checked="checked" ';
474: }
475: my $showhidden_status;
476: if ($env{'form.showhidden'}) {
477: $showhidden_status = 'checked="checked" ';
478: }
479: my $dc_title = &Apache::lonnet::plaintext('dc');
480: $output .= '<tr><td>'."\n".
481: '<label><input type="checkbox" name="showdetails" value="1" '.
482: $showdetails_status.'/>'."\n".
483: &mt('Show full details for each course ([_1] only)',$dc_title).
484: '</label>'."\n".'</td></tr><tr><td>'.
485: '<label><input type="checkbox" name="showhidden" value="1" '.
486: $showhidden_status.'/>'.
487: &mt('Include courses set to be hidden from catalog ([_1] only)',$dc_title).
488: '</label>'."\n".'</td></tr>';
489: }
490: $output .= '<tr><td>'.
491: '<label><input type="checkbox" name="showselfenroll" value="1" '.
492: $show_selfenroll_status.'/>'.
493: &mt('Only show courses which allow self-enrollment').
494: '</label></td></tr></table><br />';
495: return $output;
496: }
497:
1.16 raeburn 498: sub user_is_dc {
499: my ($codedom) = @_;
500: if (exists($env{'user.role.dc./'.$codedom.'/'})) {
501: my $livedc = 1;
502: my $now = time;
503: my ($start,$end)=split(/\./,$env{'user.role.dc./'.$codedom.'/'});
504: if ($start && $start>$now) { $livedc = 0; }
505: if ($end && $end <$now) { $livedc = 0; }
506: return $livedc;
507: }
508: return;
509: }
1.7 raeburn 510:
1.6 raeburn 511: sub recurse_options {
512: my ($currkey,$currlist,$level,$cat,$cat_options,$data,$by_year,$by_sem,$by_dept) = @_;
513: if (ref($currlist) eq 'HASH') {
514: $level ++;
515: foreach my $key (sort(keys(%{$currlist}))) {
516: $$data[$level-1]= $key;
517: &recurse_options($key,$currlist->{$key},$level,$cat,$cat_options,$data,$by_year,$by_sem,$by_dept);
518: }
519: } else {
520: $level --;
521: my @contents = split(/","/,$currlist);
522: foreach my $item (@contents) {
523: if (!grep(/^\Q$item\E$/,@{$cat_options->{$cat}})) {
524: push(@{$cat_options->{$cat}},$item);
525: }
526: if ($level == 3) {
527: if (!grep/^\Q$item\E$/,@{$by_year->{$data->[1]}->{$currkey}}) {
528: push(@{$by_year->{$data->[1]}->{$currkey}},$item);
529: }
530: if (!grep/^\Q$item\E$/,@{$by_sem->{$data->[2]}->{$currkey}}) {
531: push(@{$by_sem->{$data->[2]}->{$currkey}},$item);
532: }
533: if (!grep/^\Q$item\E$/,@{$by_dept->{$currkey}}) {
534: push(@{$by_dept->{$currkey}},$item);
535: }
536:
537: }
538: }
539: }
540: return $level;
541: }
542:
543: sub build_javascript {
544: my ($by_year,$by_sem,$by_dept,$cat_order,$codetitles) = @_;
545: my @unsorted = keys(%{$by_year});
546: my @sorted_yrs;
547: &Apache::courseclassifier::sort_cats('0',$cat_order,$codetitles,\@unsorted,\@sorted_yrs);
548: my $output = 'var idcse_by_yr_year = new Array("'.join('","',@sorted_yrs).'");'."\n".
549: 'var idcse_by_yr_dept = new Array('.scalar(@sorted_yrs).');'."\n".
550: 'var idcse_by_yr_num = new Array('.scalar(@sorted_yrs).');'."\n";
551: for (my $i=0; $i<@sorted_yrs; $i++) {
552: my $numkeys = keys(%{$by_year->{$sorted_yrs[$i]}});
553: $output .= " idcse_by_yr_num[$i] = new Array($numkeys);\n";
554: if (ref($by_year->{$sorted_yrs[$i]}) eq 'HASH') {
555: @unsorted = keys(%{$by_year->{$sorted_yrs[$i]}});
556: my @sorted_depts;
557: &Apache::courseclassifier::sort_cats('2',$cat_order,$codetitles,\@unsorted,\@sorted_depts);
558: $output .= qq| idcse_by_yr_dept[$i] = new Array ("|.join('","',@sorted_depts).'");'."\n";
559: for (my $j=0; $j<@sorted_depts; $j++) {
560: $output .= qq| idcse_by_yr_num[$i][$j] = new Array ("|;
561: $output .= join('","',sort(@{$by_year->{$sorted_yrs[$i]}->{$sorted_depts[$j]}})).'");'."\n";
562: }
563: }
564: }
565: @unsorted = keys(%{$by_sem});
566: my @sorted_sems;
567: &Apache::courseclassifier::sort_cats('1',$cat_order,$codetitles,\@unsorted,\@sorted_sems);
568: $output .= 'idcse_by_sem_sems = new Array("'.join('","',@sorted_sems).'");'."\n".
569: 'idcse_by_sem_dept = new Array('.scalar(@sorted_sems).');'."\n".
570: 'idcse_by_sem_num = new Array('.scalar(@sorted_sems).');'."\n";
571: for (my $i=0; $i<@sorted_sems; $i++) {
572: my $numkeys = keys(%{$by_sem->{$sorted_sems[$i]}});
573: $output .= " idcse_by_sem_num[$i] = new Array($numkeys);\n";
574: if (ref($by_sem->{$sorted_sems[$i]}) eq 'HASH') {
575: @unsorted = keys(%{$by_sem->{$sorted_sems[$i]}});
576: my @sorted_depts;
577: &Apache::courseclassifier::sort_cats('2',$cat_order,$codetitles,\@unsorted,\@sorted_depts);
578: $output .= qq| idcse_by_sem_dept[$i] = new Array("|.join('","',@sorted_depts).'");'."\n";
579: for (my $j=0; $j<@sorted_depts; $j++) {
580: $output .= qq| idcse_by_sem_num[$i][$j] = new Array ("|.join('","',sort(@{$by_sem->{$sorted_sems[$i]}->{$sorted_depts[$j]}})).'");'."\n";
581: }
582: }
583: }
584: @unsorted = keys(%{$by_dept});
585: my @sorted_deps;
586: &Apache::courseclassifier::sort_cats('2',$cat_order,$codetitles,\@unsorted,\@sorted_deps);
587: $output .= 'idcse_by_dep = new Array('.scalar(@sorted_deps).');'."\n";
588: for (my $k=0; $k<@sorted_deps; $k++) {
589: $output .= qq| idcse_by_dep[$k] = new Array ("|.join('","',sort(@{$by_dept->{$sorted_deps[$k]}})).'");'."\n";
590: }
591: return $output;
592: }
593:
1.28 raeburn 594: sub search_official_courselist {
1.18 raeburn 595: my ($domain,$numtitles) = @_;
596: my $instcode;
597: if (defined($numtitles) && $numtitles == 0) {
598: $instcode = '.+';
599: } else {
600: my (%codedefaults,@code_order);
601: my $defaults_result =
602: &Apache::lonnet::auto_instcode_defaults($domain,\%codedefaults,
603: \@code_order);
604: if ($defaults_result eq 'ok') {
605: $instcode ='^';
606: foreach my $item (@code_order) {
607: if ($env{'form.'.$item} eq '0' ) {
608: $instcode .= $codedefaults{$item};
609: } else {
610: $instcode .= $env{'form.'.$item};
611: }
1.7 raeburn 612: }
1.18 raeburn 613: $instcode .= '$';
614: } else {
615: $instcode = '.';
1.7 raeburn 616: }
617: }
1.32 raeburn 618: my $showhidden;
619: if (&user_is_dc($domain)) {
620: $showhidden = $env{'form.showhidden'};
621: }
622: my %courses =
623: &Apache::lonnet::courseiddump($domain,'.',1,$instcode,'.','.',undef,undef,
624: 'Course',1,$env{'form.showselfenroll'},undef,
625: $showhidden,'coursecatalog');
1.7 raeburn 626: return %courses;
627: }
628:
1.28 raeburn 629: sub search_courselist {
630: my ($domain) = @_;
631: my $cat_maxdepth = $env{'form.catalog_maxdepth'};
632: my $filter = $env{'form.currcat_'.$cat_maxdepth};
1.29 raeburn 633: if (($filter eq '') && ($cat_maxdepth > 0)) {
634: my $shallower = $cat_maxdepth - 1;
635: $filter = $env{'form.currcat_'.$shallower};
636: }
1.28 raeburn 637: my %courses;
638: if ($filter ne '') {
1.32 raeburn 639: my $showhidden;
640: if (&user_is_dc($domain)) {
641: $showhidden = $env{'form.showhidden'};
642: }
643: %courses =
644: &Apache::lonnet::courseiddump($domain,'.',1,'.','.','.',undef,undef,
645: '.',1,$env{'form.showselfenroll'},
646: $filter,$showhidden,'coursecatalog');
1.28 raeburn 647: }
648: return %courses;
649: }
1.6 raeburn 650:
1.1 raeburn 651: sub print_course_listing {
1.18 raeburn 652: my ($domain,$numtitles) = @_;
1.1 raeburn 653: my $output;
1.7 raeburn 654: my %courses;
1.15 raeburn 655: my $knownuser = &user_is_known();
1.16 raeburn 656: my $details = $env{'form.coursenum'};
657: if (&user_is_dc($domain)) {
658: if ($env{'form.showdetails'}) {
659: $details = 1;
660: }
661: }
1.7 raeburn 662: if ($env{'form.coursenum'} ne '') {
663: %courses = &Apache::lonnet::courseiddump($domain,'.',1,'.','.',
664: $env{'form.coursenum'},
1.33 raeburn 665: undef,undef,'.',1);
1.7 raeburn 666: if (keys(%courses) == 0) {
667: $output .= &mt('The courseID provided does not match a course in this domain.');
668: return $output;
669: }
1.6 raeburn 670: } else {
1.28 raeburn 671: if ($env{'form.currcat_0'} eq 'instcode::0') {
672: %courses = &search_official_courselist($domain,$numtitles);
673: } else {
674: %courses = &search_courselist($domain);
675: }
1.7 raeburn 676: if (keys(%courses) == 0) {
677: $output = &mt('No courses match the criteria you selected.');
678: return $output;
679: }
1.32 raeburn 680: if (($knownuser) && (!$env{'form.showdetails'}) && (!&user_is_dc($domain))) {
1.31 bisitz 681: $output = '<b>'.&mt('Note for students:').'</b> '
682: .&mt('If you are officially enrolled in a course but the course is not listed in your LON-CAPA courses, click the "Show more details" link for the specific course and check the default access dates and/or automated enrollment settings.')
683: .'<br /><br />';
1.8 raeburn 684: }
1.7 raeburn 685: }
1.27 raeburn 686: my $now = time;
687: my %domconfig =
688: &Apache::lonnet::get_dom('configuration',['usercreation'],$domain);
689: $output .= &construct_data_table($knownuser,\%courses,$details,undef,$now,\%domconfig);
1.16 raeburn 690: $output .= &Apache::lonhtmlcommon::echo_form_input(['coursenum','state','catalogfilter','sortby','showdetails']);
1.15 raeburn 691: return $output;
692: }
693:
694: sub construct_data_table {
1.27 raeburn 695: my ($knownuser,$courses,$details,$usersections,$now,$domconfig) = @_;
1.7 raeburn 696: my %sortname;
1.16 raeburn 697: if (($details eq '') || ($env{'form.showdetails'})) {
1.7 raeburn 698: $sortname{'Code'} = 'code';
699: $sortname{'Title'} = 'title';
1.22 raeburn 700: $sortname{'Owner(s)'} = 'owner';
1.7 raeburn 701: }
1.15 raeburn 702: my $output = &Apache::loncommon::start_data_table().
703: &Apache::loncommon::start_data_table_header_row();
1.24 raeburn 704: my @coltitles = ('Count','Code','Sections','Crosslisted','Title','Owner(s)');
1.15 raeburn 705: if (ref($usersections) eq 'HASH') {
706: $coltitles[1] = 'Your Section';
707: }
1.7 raeburn 708: foreach my $item (@coltitles) {
709: $output .= '<th>';
710: if (defined($sortname{$item})) {
711: $output .= '<a href="javascript:changeSort('."'$sortname{$item}'".')">'.&mt($item).'</a>';
1.24 raeburn 712: } elsif ($item eq 'Count') {
713: $output .= ' ';
1.7 raeburn 714: } else {
715: $output .= &mt($item);
716: }
717: $output .= '</th>';
1.1 raeburn 718: }
1.15 raeburn 719: if ($knownuser) {
720: if ($details) {
1.8 raeburn 721: $output .=
1.7 raeburn 722: '<th>'.&mt('Default Access Dates for Students').'</th>'.
723: '<th>'.&mt('Student Counts').'</th>'.
724: '<th>'.&mt('Auto-enrollment of <br />registered students').'</th>';
1.15 raeburn 725: } else {
1.27 raeburn 726: $output .= '<th>'.&mt('Details').'</th>';
1.8 raeburn 727: }
1.1 raeburn 728: }
1.27 raeburn 729: $output .= '<th>'.&mt('Self-enroll (if permitted)').'</th>';
1.7 raeburn 730: &Apache::loncommon::end_data_table_header_row();
1.15 raeburn 731: my %courseinfo = &build_courseinfo_hash($courses,$knownuser,$details,
732: $usersections);
1.7 raeburn 733: my %Sortby;
1.15 raeburn 734: foreach my $course (sort(keys(%{$courses}))) {
1.7 raeburn 735: if ($env{'form.sortby'} eq 'code') {
736: push(@{$Sortby{$courseinfo{$course}{'code'}}},$course);
737: } elsif ($env{'form.sortby'} eq 'owner') {
1.22 raeburn 738: push(@{$Sortby{$courseinfo{$course}{'ownerlastnames'}}},$course);
1.7 raeburn 739: } else {
1.25 raeburn 740: my $clean_title = $courseinfo{$course}{'title'};
741: $clean_title =~ s/\W+//g;
742: if ($clean_title eq '') {
743: $clean_title = $courseinfo{$course}{'title'};
744: }
745: push(@{$Sortby{$clean_title}},$course);
1.7 raeburn 746: }
747: }
748: my @sorted_courses;
749: if (($env{'form.sortby'} eq 'code') || ($env{'form.sortby'} eq 'owner')) {
750: @sorted_courses = sort(keys(%Sortby));
1.6 raeburn 751: } else {
1.7 raeburn 752: @sorted_courses = sort { lc($a) cmp lc($b) } (keys(%Sortby));
1.1 raeburn 753: }
1.24 raeburn 754: my $count = 1;
1.7 raeburn 755: foreach my $item (@sorted_courses) {
756: foreach my $course (@{$Sortby{$item}}) {
757: $output.=&Apache::loncommon::start_data_table_row();
1.27 raeburn 758: $output.=&courseinfo_row($courseinfo{$course},$knownuser,
759: $details,\$count,$now,$course);
1.7 raeburn 760: $output.=&Apache::loncommon::end_data_table_row();
761: }
1.1 raeburn 762: }
1.7 raeburn 763: $output .= &Apache::loncommon::end_data_table();
764: return $output;
765: }
766:
767: sub build_courseinfo_hash {
1.15 raeburn 768: my ($courses,$knownuser,$details,$usersections) = @_;
1.1 raeburn 769: my %courseinfo;
1.7 raeburn 770: my $now = time;
1.15 raeburn 771: foreach my $course (keys(%{$courses})) {
1.1 raeburn 772: my $descr;
1.22 raeburn 773: if (ref($courses->{$course}) eq 'HASH') {
774: $descr = $courses->{$course}{'description'};
1.1 raeburn 775: }
776: my $cleandesc=&HTML::Entities::encode($descr,'<>&"');
777: $cleandesc=~s/'/\\'/g;
1.10 raeburn 778: $cleandesc =~ s/^\s+//;
1.1 raeburn 779: my ($cdom,$cnum)=split(/\_/,$course);
1.27 raeburn 780: my ($descr,$instcode,$singleowner,$ttype,$selfenroll_types,
781: $selfenroll_start,$selfenroll_end,@owners,%ownernames);
1.22 raeburn 782: if (ref($courses->{$course}) eq 'HASH') {
783: $descr = $courses->{$course}{'description'};
1.23 raeburn 784: $instcode = $courses->{$course}{'inst_code'};
1.22 raeburn 785: $singleowner = $courses->{$course}{'owner'};
786: $ttype = $courses->{$course}{'type'};
1.27 raeburn 787: $selfenroll_types = $courses->{$course}{'selfenroll_types'};
788: $selfenroll_start = $courses->{$course}{'selfenroll_start_date'};
789: $selfenroll_end = $courses->{$course}{'selfenroll_end_date'};
1.22 raeburn 790: push(@owners,$singleowner);
791: if (ref($courses->{$course}{'co-owners'}) eq 'ARRAY') {
792: foreach my $item (@{$courses->{$course}{'co-owners'}}) {
793: push(@owners,$item);
794: }
795: }
796: }
797: foreach my $owner (@owners) {
798: my ($ownername,$ownerdom) = @_;
799: if ($owner =~ /:/) {
800: ($ownername,$ownerdom) = split(/:/,$owner);
801: } else {
802: $ownername = $owner;
803: if ($owner ne '') {
804: $ownerdom = $cdom;
805: }
806: }
807: if ($ownername ne '' && $ownerdom ne '') {
808: my %namehash=&Apache::loncommon::getnames($ownername,$ownerdom);
809: $ownernames{$ownername.':'.$ownerdom} = \%namehash;
1.1 raeburn 810: }
811: }
812: $courseinfo{$course}{'cdom'} = $cdom;
813: $courseinfo{$course}{'cnum'} = $cnum;
814: $courseinfo{$course}{'code'} = $instcode;
1.22 raeburn 815: my @lastnames;
816: foreach my $owner (keys(%ownernames)) {
817: if (ref($ownernames{$owner}) eq 'HASH') {
818: push(@lastnames,$ownernames{$owner}{'lastname'});
819: }
820: }
821: $courseinfo{$course}{'ownerlastnames'} = join(', ',sort(@lastnames));
1.1 raeburn 822: $courseinfo{$course}{'title'} = $cleandesc;
1.22 raeburn 823: $courseinfo{$course}{'owner'} = $singleowner;
1.27 raeburn 824: $courseinfo{$course}{'selfenroll_types'} = $selfenroll_types;
825: $courseinfo{$course}{'selfenroll_start'} = $selfenroll_start;
826: $courseinfo{$course}{'selfenroll_end'} = $selfenroll_end;
1.7 raeburn 827:
828: my %coursehash = &Apache::lonnet::dump('environment',$cdom,$cnum);
829: my @classids;
830: my @crosslistings;
1.15 raeburn 831: my ($seclist,$numsec) =
832: &identify_sections($coursehash{'internal.sectionnums'});
833: if (ref($usersections) eq 'HASH') {
834: if (ref($usersections->{$course}) eq 'ARRAY') {
835: $seclist = join(', ',@{$usersections->{$course}});
836: }
837: }
1.7 raeburn 838: $courseinfo{$course}{'seclist'} = $seclist;
1.15 raeburn 839: my ($xlist_items,$numxlist) =
840: &identify_sections($coursehash{'internal.crosslistings'});
1.7 raeburn 841: my $showsyllabus = 1; # default is to include a syllabus link
842: if (defined($coursehash{'showsyllabus'})) {
843: $showsyllabus = $coursehash{'showsyllabus'};
844: }
845: $courseinfo{$course}{'showsyllabus'} = $showsyllabus;
1.15 raeburn 846: if (((defined($env{'form.coursenum'}) && ($cnum eq $env{'form.coursenum'}))) ||
1.22 raeburn 847: ($knownuser && ($details == 1))) {
1.15 raeburn 848: $courseinfo{$course}{'counts'} = &count_students($cdom,$cnum,$numsec);
849: $courseinfo{$course}{'autoenrollment'} =
850: &autoenroll_info(\%coursehash,$now,$seclist,$xlist_items,
1.22 raeburn 851: $instcode,\@owners,$cdom,$cnum);
1.15 raeburn 852:
853: my $startaccess = '';
854: my $endaccess = '';
855: my $accessdates;
856: if ( defined($coursehash{'default_enrollment_start_date'}) ) {
857: $startaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_start_date'});
858: }
859: if ( defined($coursehash{'default_enrollment_end_date'}) ) {
860: $endaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_end_date'});
861: if ($coursehash{'default_enrollment_end_date'} == 0) {
1.34 ! raeburn 862: $endaccess = &mt('No ending date');
1.15 raeburn 863: }
864: }
865: if ($startaccess) {
866: $accessdates .= &mt('<i>From:</i> ').$startaccess.'<br />';
1.7 raeburn 867: }
1.15 raeburn 868: if ($endaccess) {
869: $accessdates .= &mt('<i>To:</i> ').$endaccess.'<br />';
870: }
1.34 ! raeburn 871: if (($selfenroll_types ne '') &&
! 872: ($selfenroll_end > 0 && $selfenroll_end > $now)) {
! 873: my ($selfenroll_start_access,$selfenroll_end_access);
! 874: if (($coursehash{'default_enrollment_start_date'} ne
! 875: $coursehash{'internal.selfenroll_start_access'}) ||
! 876: ($coursehash{'default_enrollment_end_date'} ne
! 877: $coursehash{'internal.selfenroll_end_access'})) {
! 878: if ( defined($coursehash{'internal.selfenroll_start_access'}) ) {
! 879: $selfenroll_start_access = &Apache::lonlocal::locallocaltime($coursehash{'internal.selfenroll_start_access'});
! 880: }
! 881: if ( defined($coursehash{'default_enrollment_end_date'}) ) {
! 882: $selfenroll_end_access = &Apache::lonlocal::locallocaltime($coursehash{'internal.selfenroll_end_access'});
! 883: if ($coursehash{'internal.selfenroll_end_access'} == 0) {
! 884: $selfenroll_end_access = &mt('No ending date');
! 885: }
! 886: }
! 887: if ($selfenroll_start_access || $selfenroll_end_access) {
! 888: $accessdates .= '<br/><br /><i>'.&mt('Self-enrollers:').'</i><br />';
! 889: if ($selfenroll_start_access) {
! 890: $accessdates .= &mt('<i>From:</i> ').$selfenroll_start_access.'<br />';
! 891: }
! 892: if ($selfenroll_end_access) {
! 893: $accessdates .= &mt('<i>To:</i> ').$selfenroll_end_access.'<br />';
! 894: }
! 895: }
! 896: }
! 897: }
1.15 raeburn 898: $courseinfo{$course}{'access'} = $accessdates;
1.1 raeburn 899: }
1.7 raeburn 900: if ($xlist_items eq '') {
901: $xlist_items = &mt('No');
1.1 raeburn 902: }
1.7 raeburn 903: $courseinfo{$course}{'xlist'} = $xlist_items;
1.1 raeburn 904: }
1.7 raeburn 905: return %courseinfo;
1.1 raeburn 906: }
907:
1.7 raeburn 908: sub count_students {
1.15 raeburn 909: my ($cdom,$cnum,$numsec) = @_;
1.1 raeburn 910: my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cnum);
1.7 raeburn 911: my %student_count = (
912: Active => 0,
913: Future => 0,
914: Expired => 0,
915: );
1.1 raeburn 916: my %idx;
917: $idx{'status'} = &Apache::loncoursedata::CL_STATUS();
1.4 albertel 918: my %status_title = &Apache::lonlocal::texthash(
1.1 raeburn 919: Expired => 'Previous access',
920: Active => 'Current access',
921: Future => 'Future access',
922: );
1.7 raeburn 923:
1.4 albertel 924: while (my ($student,$data) = each(%$classlist)) {
1.1 raeburn 925: $student_count{$data->[$idx{'status'}]} ++;
926: }
1.7 raeburn 927:
1.15 raeburn 928: my $countslist = &mt('[quant,_1,section]',$numsec).':<br />';
1.7 raeburn 929: foreach my $status ('Active','Future') {
1.1 raeburn 930: $countslist .= '<nobr>'.$status_title{$status}.': '.
931: $student_count{$status}.'</nobr><br />';
932: }
1.7 raeburn 933: return $countslist;
934: }
935:
936: sub courseinfo_row {
1.27 raeburn 937: my ($info,$knownuser,$details,$countref,$now,$course) = @_;
1.7 raeburn 938: my ($cdom,$cnum,$title,$ownerlast,$code,$owner,$seclist,$xlist_items,
939: $accessdates,$showsyllabus,$counts,$autoenrollment,$output);
940: if (ref($info) eq 'HASH') {
941: $cdom = $info->{'cdom'};
942: $cnum = $info->{'cnum'};
943: $title = $info->{'title'};
1.22 raeburn 944: $ownerlast = $info->{'ownerlastnames'};
1.7 raeburn 945: $code = $info->{'code'};
946: $owner = $info->{'owner'};
947: $seclist = $info->{'seclist'};
948: $xlist_items = $info->{'xlist'};
949: $accessdates = $info->{'access'};
950: $counts = $info->{'counts'};
951: $autoenrollment = $info->{'autoenrollment'};
952: $showsyllabus = $info->{'showsyllabus'};
953: } else {
954: $output = '<td colspan="8">'.&mt('No information available for [_1].',
955: $code).'</td>';
956: return $output;
1.2 raeburn 957: }
1.24 raeburn 958: $output .= '<td>'.$$countref.'</td>'.
959: '<td>'.$code.'</td>'.
1.7 raeburn 960: '<td>'.$seclist.'</td>'.
961: '<td>'.$xlist_items.'</td>'.
962: '<td>'.$title.' <font size="-2">';
1.2 raeburn 963: if ($showsyllabus) {
964: $output .= &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$cnum,$cdom);
1.7 raeburn 965: } else {
966: $output .= ' ';
1.2 raeburn 967: }
968: $output .= '</font></td>'.
1.7 raeburn 969: '<td>'.$ownerlast.'</td>';
1.15 raeburn 970: if ($knownuser) {
971: if ($details) {
1.8 raeburn 972: $output .=
1.7 raeburn 973: '<td>'.$accessdates.'</td>'.
974: '<td>'.$counts.'</td>'.
975: '<td>'.$autoenrollment.'</td>';
1.15 raeburn 976: } else {
977: $output .= "<td><a href=\"javascript:setCourseId('$cnum')\">".&mt('Show more details').'</a></td>';
1.8 raeburn 978: }
1.7 raeburn 979: }
1.27 raeburn 980: my $selfenroll;
981: if ($info->{'selfenroll_types'}) {
982: my $showstart = &Apache::lonlocal::locallocaltime($info->{'selfenroll_start'});
983: my $showend = &Apache::lonlocal::locallocaltime($info->{'selfenroll_end'});
984: if (($info->{'selfenroll_end'} > 0) && ($info->{'selfenroll_end'} > $now)) {
985: if (($info->{'selfenroll_start'} > 0) && ($info->{'selfenroll_start'} > $now)) {
986: $output .= '<td>'.&mt('Starts: [_1]','<span class="LC_cusr_emph">'.$showstart.'</span>').'<br />'.&mt('Ends: [_1]','<span class="LC_cusr_emph">'.$showend.'</span>').'</td>';
987: } else {
988: $output .= '<td><a href="/adm/selfenroll?cid='.$course.'">'.&mt('Enroll in course').'</a></td>';
989: }
990: $selfenroll = 1;
991: }
992: }
993: if (!$selfenroll) {
994: $output .= '<td> </td>';
995: }
1.24 raeburn 996: $$countref ++;
1.1 raeburn 997: return $output;
998: }
999:
1000: sub identify_sections {
1001: my ($seclist) = @_;
1002: my @secnums;
1003: if ($seclist =~ /,/) {
1.4 albertel 1004: my @sections = split(/,/,$seclist);
1.1 raeburn 1005: foreach my $sec (@sections) {
1006: $sec =~ s/:[^:]*$//;
1007: push(@secnums,$sec);
1008: }
1009: } else {
1010: if ($seclist =~ m/^([^:]+):/) {
1011: my $sec = $1;
1.4 albertel 1012: if (!grep(/^\Q$sec\E$/,@secnums)) {
1013: push(@secnums,$sec);
1.1 raeburn 1014: }
1015: }
1016: }
1017: @secnums = sort {$a <=> $b} @secnums;
1018: my $seclist = join(', ',@secnums);
1.15 raeburn 1019: my $numsec = @secnums;
1020: return ($seclist,$numsec);
1.1 raeburn 1021: }
1022:
1.2 raeburn 1023: sub get_valid_classes {
1.22 raeburn 1024: my ($seclist,$xlist_items,$crscode,$owners,$cdom,$cnum) = @_;
1.2 raeburn 1025: my $response;
1026: my %validations;
1027: @{$validations{'sections'}} = ();
1028: @{$validations{'xlists'}} = ();
1029: my $totalitems = 0;
1030: if ($seclist) {
1.13 raeburn 1031: foreach my $sec (split(/, /,$seclist)) {
1.2 raeburn 1032: my $class = $crscode.$sec;
1.22 raeburn 1033: if (&Apache::lonnet::auto_validate_class_sec($cdom,$cnum,$owners,
1.3 albertel 1034: $class) eq 'ok') {
1.2 raeburn 1035: if (!grep(/^\Q$sec$\E/,@{$validations{'sections'}})) {
1.4 albertel 1036: push(@{$validations{'sections'}},$sec);
1.2 raeburn 1037: $totalitems ++;
1038: }
1039: }
1040: }
1041: }
1042: if ($xlist_items) {
1.13 raeburn 1043: foreach my $item (split(/, /,$xlist_items)) {
1.22 raeburn 1044: if (&Apache::lonnet::auto_validate_class_sec($cdom,$cnum,$owners,
1.3 albertel 1045: $item) eq 'ok') {
1.2 raeburn 1046: if (!grep(/^\Q$item$\E/,@{$validations{'xlists'}})) {
1.4 albertel 1047: push(@{$validations{'xlists'}},$item);
1.2 raeburn 1048: $totalitems ++;
1049: }
1050: }
1051: }
1052: }
1053: if ($totalitems > 0) {
1054: if (@{$validations{'sections'}}) {
1055: $response = &mt('Sections: ').
1.14 raeburn 1056: join(', ',@{$validations{'sections'}}).'<br />';
1.2 raeburn 1057: }
1058: if (@{$validations{'xlists'}}) {
1059: $response .= &mt('Courses: ').
1.14 raeburn 1060: join(', ',@{$validations{'xlists'}});
1.2 raeburn 1061: }
1062: }
1063: return $response;
1064: }
1065:
1.6 raeburn 1066: sub javascript_select_filler {
1067: my ($formname,$scripttext,$codetitles,$longtitles_str,$allidlist) = @_;
1068: my $output = <<END;
1069: function courseSet() {
1070: var longtitles = new Array ("$longtitles_str");
1071: var valyr = document.$formname.Year.options[document.$formname.Year.selectedIndex].value
1072: var valsem = document.$formname.Semester.options[document.$formname.Semester.selectedIndex].value
1073: var valdept = document.$formname.Department.options[document.$formname.Department.selectedIndex].value
1074: var valclass = document.$formname.Number.options[document.$formname.Number.selectedIndex].value
1075: var idyears = new Array("$allidlist");
1076: var idyr = -1;
1077: var idsem = -1;
1078: var iddept = -1;
1079: document.$formname.Number.length = 0;
1080:
1081: $scripttext
1082:
1083: selYear = document.$formname.Year.selectedIndex-1;
1084: selSemester = document.$formname.Semester.selectedIndex-1;
1085: selDepartment = document.$formname.Department.selectedIndex-1;
1086: if (selYear == -1) {
1087: if (selSemester == -1) {
1088: if (selDepartment > -1) {
1089: document.$formname.Number.options[0] = new Option('All','0',false,false);
1090: for (var k=0; k<idcse_by_dep[selDepartment].length; k++) {
1091: document.$formname.Number.options[k+1] = new Option(idcse_by_dep[selDepartment][k],idcse_by_dep[selDepartment][k],false,false);
1092:
1093: }
1094: }
1095: else {
1096: document.$formname.Number.options[0] = new Option("All","0",true,true);
1097: }
1098: }
1099: else {
1100: if (selDepartment > -1) {
1101: for (var i=0; i<idcse_by_sem_sems.length; i++) {
1102: if (idcse_by_sem_sems[i] == valsem) {
1103: idsem = i;
1104: }
1105: }
1106: if (idsem != -1) {
1107: for (var i=0; i<idcse_by_sem_dept[idsem].length; i++) {
1108: if (idcse_by_sem_dept[idsem][i] == valdept) {
1109: iddept = i;
1110: }
1111: }
1112: }
1113: if (iddept != -1) {
1114: document.$formname.Number.options[0] = new Option('All','0',false,false);
1115: for (var k=0; k<idcse_by_sem_num[idsem][iddept].length; k++) {
1116: document.$formname.Number.options[k+1] = new Option(idcse_by_sem_num[idsem][iddept][k],idcse_by_sem_num[idsem][iddept][k],false,false);
1117: }
1118: }
1119: else {
1120: document.$formname.Number.options[0] = new Option('No courses','0',true,true);
1121: }
1122: }
1123: else {
1124: document.$formname.Number.options[0] = new Option("All","0",true,true);
1125: }
1126: }
1127: }
1128: else {
1129: if (selSemester == -1) {
1130: if (selDepartment > -1) {
1131: for (var i=0; i<idcse_by_yr_year.length; i++) {
1132: if (idcse_by_yr_year[i] == valyr) {
1133: idyr = i;
1134: }
1135: }
1136: if (idyr != -1) {
1137: for (var i=0; i<idcse_by_yr_dept[idyr].length; i++) {
1138: if (idcse_by_yr_dept[idyr][i] == valdept) {
1139: iddept = i;
1140: }
1141: }
1142: }
1143: if (iddept != -1) {
1144: document.$formname.Number.options[0] = new Option('All','0',false,false);
1145: for (var k=0; k<idcse_by_yr_num[idyr][iddept].length; k++) {
1146: document.$formname.Number.options[k+1] = new Option(idcse_by_yr_num[idyr][iddept][k],idcse_by_yr_num[idyr][iddept][k],false,false);
1147: }
1148: }
1149: else {
1150: document.$formname.Number.options[0] = new Option('No courses','0',true,true);
1151: }
1152: }
1153: else {
1154: document.$formname.Number.options[0] = new Option("All","0",true,true);
1155: }
1156: }
1157: else {
1.9 raeburn 1158: if (selDepartment > -1) {
1159: for (var k=0; k<idyears.length; k++) {
1160: if (idyears[k] == valyr) {
1161: idyr = k;
1162: }
1.6 raeburn 1163: }
1.9 raeburn 1164: if (idyr != -1) {
1165: for (var k=0; k<idsems[idyr].length; k++) {
1166: if (idsems[idyr][k] == valsem) {
1167: idsem = k;
1168: }
1.6 raeburn 1169: }
1170: }
1.9 raeburn 1171: if (idsem != -1) {
1172: for (var k=0; k<idcodes[idyr][idsem].length; k++) {
1173: if (idcodes[idyr][idsem][k] == valdept) {
1174: iddept = k;
1175: }
1.6 raeburn 1176: }
1177: }
1.9 raeburn 1178: if (iddept != -1) {
1179: document.$formname.Number.options[0] = new Option('All','0',false,false);
1180: for (var i=0; i<idcourses[idyr][idsem][iddept].length; i++) {
1181: var display = idcourses[idyr][idsem][iddept][i];
1182: if (longtitles[3] == 1) {
1183: if (idcourseslongs[idyr][idsem][iddept][i] != "") {
1184: display = idcourseslongs[idyr][idsem][iddept][i]
1185: }
1.6 raeburn 1186: }
1.9 raeburn 1187: document.$formname.Number.options[i+1] = new Option(display,idcourses[idyr][idsem][iddept][i],false,false)
1.6 raeburn 1188: }
1.9 raeburn 1189: }
1190: else {
1191: document.$formname.Number.options[0] = new Option('No courses','0',true,true);
1.6 raeburn 1192: }
1.9 raeburn 1193: }
1.6 raeburn 1194: else {
1.9 raeburn 1195: document.$formname.Number.options[0] = new Option('All','0',true,true);
1.6 raeburn 1196: }
1197: }
1198: document.$formname.Number.selectedIndex = 0
1199: }
1200: }
1201: END
1202: return $output;
1203: }
1.1 raeburn 1204:
1.7 raeburn 1205: sub autoenroll_info {
1.22 raeburn 1206: my ($coursehash,$now,$seclist,$xlist_items,$code,$owners,$cdom,$cnum) = @_;
1.7 raeburn 1207: my $autoenrolldates = &mt('Not enabled');
1208: if (defined($coursehash->{'internal.autoadds'}) && $coursehash->{'internal.autoadds'} == 1) {
1209: my ($autostart,$autoend);
1210: if ( defined($coursehash->{'internal.autostart'}) ) {
1211: $autostart = &Apache::lonlocal::locallocaltime($coursehash->{'internal.autostart'});
1212: }
1213: if ( defined($coursehash->{'internal.autoend'}) ) {
1214: $autoend = &Apache::lonlocal::locallocaltime($coursehash->{'internal.autoend'});
1215: }
1216: if ($coursehash->{'internal.autostart'} > $now) {
1217: if ($coursehash->{'internal.autoend'} && $coursehash->{'internal.autoend'} < $now) {
1218: $autoenrolldates = &mt('Not enabled');
1219: } else {
1220: my $valid_classes =
1221: &get_valid_classes($seclist,$xlist_items,$code,
1.22 raeburn 1222: $owners,$cdom,$cnum);
1.7 raeburn 1223: if ($valid_classes ne '') {
1224: $autoenrolldates = &mt('Not enabled<br />Starts: ').
1225: $autostart.'<br />'.$valid_classes; }
1226: }
1227: } else {
1228: if ($coursehash->{'internal.autoend'} && $coursehash->{'internal.autoend'} < $now) {
1229: $autoenrolldates = &mt('Not enabled<br />Ended: ').$autoend;
1230: } else {
1231: my $valid_classes = &get_valid_classes($seclist,$xlist_items,
1.22 raeburn 1232: $code,$owners,$cdom,$cnum);
1.7 raeburn 1233: if ($valid_classes ne '') {
1234: $autoenrolldates = &mt('Currently enabled<br />').
1235: $valid_classes;
1236: }
1237: }
1238: }
1239: }
1240: return $autoenrolldates;
1241: }
1242:
1.8 raeburn 1243: sub user_is_known {
1244: my $known = 0;
1245: if ($env{'user.name'} ne '' && $env{'user.name'} ne 'public'
1246: && $env{'user.domain'} ne '' && $env{'user.domain'} ne 'public') {
1247: $known = 1;
1248: }
1249: return $known;
1250: }
1251:
1.1 raeburn 1252: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>