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