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