Annotation of loncom/interface/coursecatalog.pm, revision 1.85
1.17 albertel 1: # The LearningOnline Network with CAPA
2: # Handler for displaying the course catalog interface
3: #
1.85 ! raeburn 4: # $Id: coursecatalog.pm,v 1.84 2014/04/28 22:12:55 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);
1.38 raeburn 56: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
57: ['sortby','showdom']);
1.28 raeburn 58:
59: my $codedom = &Apache::lonnet::default_login_domain();
1.19 raeburn 60:
61: if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne 'public')) {
62: $codedom = $env{'user.domain'};
63: if ($env{'request.role.domain'} ne '') {
64: $codedom = $env{'request.role.domain'};
65: }
66: }
1.7 raeburn 67: my $formname = 'coursecatalog';
1.28 raeburn 68: if ($env{'form.showdom'} ne '') {
1.75 raeburn 69: $env{'form.showdom'} = &LONCAPA::clean_domain($env{'form.showdom'});
1.28 raeburn 70: if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') {
71: $codedom = $env{'form.showdom'};
1.75 raeburn 72: } else {
73: $env{'form.showdom'} = '';
1.28 raeburn 74: }
75: }
1.20 albertel 76: my $domdesc = &Apache::lonnet::domain($codedom,'description');
1.7 raeburn 77: &Apache::lonhtmlcommon::clear_breadcrumbs();
1.35 raeburn 78:
79: my %domconfig =
80: &Apache::lonnet::get_dom('configuration',['coursecategories'],$codedom);
1.82 raeburn 81: my $knownuser = &user_is_known();
82:
83: my ($cathash,$cattype);
1.35 raeburn 84: if (ref($domconfig{'coursecategories'}) eq 'HASH') {
85: $cathash = $domconfig{'coursecategories'}{'cats'};
1.82 raeburn 86: if ($knownuser) {
87: $cattype = $domconfig{'coursecategories'}{'auth'};
88: } else {
89: $cattype = $domconfig{'coursecategories'}{'unauth'};
90: }
1.85 ! raeburn 91: if ($cattype eq '') {
! 92: $cattype = 'std';
! 93: }
1.35 raeburn 94: } else {
95: $cathash = {};
1.83 raeburn 96: $cattype = 'std';
1.82 raeburn 97: }
98: if ($cattype eq 'none') {
99: $r->print(&Apache::loncommon::start_page('Course/Community Catalog'));
100: &Apache::lonhtmlcommon::add_breadcrumb
101: ({href=>"/adm/coursecatalog",
102: text=>"Course/Community Catalog"});
103: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog'));
104: if ($knownuser) {
105: $r->print('<div>'.&mt('No catalog of LON-CAPA courses/communities is provided for: [_1]',$domdesc).'</div>');
106: } else {
107: if ($domconfig{'coursecategories'}{'auth'} eq 'none') {
108: $r->print('<div>'.&mt('No catalog of LON-CAPA courses/communities is provided for: [_1]',$domdesc).'</div>');
109: } else {
110: $r->print('<div>'.&mt('The catalog of LON-CAPA courses/communities provided for: "[_1]" is only available to users who are logged in.',$domdesc).'</div>');
111: }
112: }
113: $r->print(&Apache::loncommon::end_page());
114: return OK;
115: }
116:
117: my $cnum;
118: if ($cattype eq 'codesrch') {
119: my ($uniquecode,$codemsg,$brtext);
120: if ($env{'form.uniquecode'}) {
121: $uniquecode = $env{'form.uniquecode'};
122: $uniquecode =~ s/^\s+|\s+$//g;
123: }
124: my $js = '<script type="text/javascript">'."\n".
125: '// <![CDATA['."\n".
126: &courselink_javascript()."\n".
127: '// ]]>'."\n".
128: '</script>'."\n";
129: $r->print(&Apache::loncommon::start_page('Search for a Course/Community',$js));
130: if ($uniquecode =~ /^\w{6}$/) {
131: &Apache::lonhtmlcommon::add_breadcrumb
132: ({href=>"/adm/coursecatalog",
133: text=>"Course/Community Catalog"});
134: $brtext = 'Search Result';
135: } else {
136: $brtext = 'Course/Community Catalog';
137: }
138: &Apache::lonhtmlcommon::add_breadcrumb
139: ({href=>"/adm/coursecatalog",
140: text=>"$brtext"});
141: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog'));
142: $r->print(&coursesearch($codedom,$domdesc,$uniquecode));
143: if ($uniquecode =~ /^\w{6}$/) {
144: $r->print('<hr />');
145: my $confname = $codedom.'-domainconfig';
146: my %codes = &Apache::lonnet::get('uniquecodes',[$uniquecode],$codedom,$confname);
147: if ($codes{$uniquecode}) {
148: $cnum = $codes{$uniquecode};
149: my %courses = &Apache::lonnet::courseiddump($codedom,'.',1,'.','.',
150: $cnum,undef,undef,'.',1);
151: if (keys(%courses)) {
152: $env{'form.coursenum'} = $cnum;
153: my %courseinfo = &build_courseinfo_hash(\%courses,$knownuser,$codedom);
154: undef($env{'form.coursenum'});
155: if (ref($courseinfo{$codedom.'_'.$cnum}) eq 'HASH') {
156: $r->print(&Apache::lonhtmlcommon::start_pick_box());
157: my @cols = ('title','ownerlastnames','seclist','access');
158: my %lt = &Apache::lonlocal::texthash(
159: title => 'Title',
160: ownerlastnames => 'Owner & Co-owner(s)',
161: seclist => 'Sections',
162: access => 'Default Access Dates for Students',
163: );
164: my @shown;
165: foreach my $item (@cols) {
166: if ($courseinfo{$codedom.'_'.$cnum}{$item}) {
167: push(@shown,$item);
168: }
169: }
170: my $num = 0;
171: foreach my $item (@shown) {
172: $num ++;
173: $r->print(&Apache::lonhtmlcommon::row_title($lt{$item}).
174: $courseinfo{$codedom.'_'.$cnum}{$item});
175: if ($item eq 'title') {
176: if ($courseinfo{$codedom.'_'.$cnum}{'showsyllabus'}) {
177: $r->print(' <font size="-2">'.
178: '<a href="javascript:ToSyllabus('."'$codedom','$cnum'".')">'.
179: &mt('Syllabus').'</a></font>');
180: }
181: }
182: my $arg = ( $num == scalar(@shown) ? 1 : '' );
183: $r->print(&Apache::lonhtmlcommon::row_closure($arg));
184: }
185: $r->print(&Apache::lonhtmlcommon::end_pick_box());
186: my $selfenroll = &selfenroll_status($courseinfo{$codedom.'_'.$cnum},$codedom.'_'.$cnum);
187: if ($selfenroll) {
188: $r->print('<br />'.$selfenroll);
189: }
190: $r->print('<form name="linklaunch" method="post" action="">'."\n".
191: '<input type="hidden" name="backto" value="coursecatalog" />'."\n".
192: '<input type="hidden" name="courseid" value="" />'."\n".
193: '</form>'."\n");
194:
195: } else {
196: $codemsg = &mt('Code matched, but course ID to which this mapped is invalid.');
197: }
198: } else {
199: $codemsg = &mt('Code matched, but course ID to which this mapped is invalid.');
200: }
201: } else {
202: $codemsg = &mt('No match');
203: }
204: }
205: $r->print('<br />'.&Apache::loncommon::end_page());
206: return OK;
207: } else {
208: if ($env{'form.coursenum'}) {
209: $cnum = $env{'form.coursenum'};
210: }
1.35 raeburn 211: }
1.82 raeburn 212:
213: if ($env{'form.catalog_maxdepth'} ne '') {
214: $env{'form.catalog_maxdepth'} =~ s{\D}{}g;
215: }
216:
217: my (@cats,@trails,%allitems,%idx,@jsarray,%subcathash,$subcats);
1.36 raeburn 218: if ($env{'form.withsubcats'}) {
219: $subcats = \%subcathash;
220: }
1.35 raeburn 221: &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,\%allitems,
1.36 raeburn 222: \%idx,\@jsarray,$subcats);
1.63 raeburn 223: my ($numtitles,@codetitles);
1.82 raeburn 224: if (($env{'form.coursenum'} ne '') && ($knownuser)) {
1.63 raeburn 225: &course_details($r,$codedom,$formname,$domdesc,\@trails,\%allitems,\@codetitles);
1.7 raeburn 226: } else {
1.46 raeburn 227: my ($catlinks,$has_subcats,$selitem) = &category_breadcrumbs($codedom,@cats);
1.72 raeburn 228: my $wasacctext = &get_wasactive_text();
1.28 raeburn 229: my $catjs = <<"ENDSCRIPT";
230:
231: function setCatDepth(depth) {
232: document.coursecats.catalog_maxdepth.value = depth;
1.36 raeburn 233: if (depth == '') {
234: document.coursecats.currcat_0.value = '';
235: }
1.28 raeburn 236: document.coursecats.submit();
237: return;
238: }
239:
1.33 raeburn 240: function changeSort(caller) {
241: document.$formname.sortby.value = caller;
242: document.$formname.submit();
243: }
1.40 raeburn 244:
1.33 raeburn 245: function setCourseId(caller) {
246: document.$formname.coursenum.value = caller;
247: document.$formname.submit();
1.37 raeburn 248: }
249:
250: ENDSCRIPT
1.72 raeburn 251: $catjs .= &courselink_javascript();
252: if (&user_is_dc($codedom)) {
253: $catjs .= <<ENDTOGGJS
254:
255: function toggleStatuses() {
256: if (document.$formname.showdetails.checked) {
257: document.getElementById('statuschoice').style.display='block';
258: document.getElementById('statuscell').style.borderLeft='1px solid';
259: } else {
260: document.getElementById('statuschoice').style.display='none';
261: document.getElementById('statuscell').style.borderLeft='0px';
262: }
263: return;
264: }
265:
266: function toggleWasActive() {
267: if (document.getElementById('counts_Previous')) {
268: if (document.getElementById('counts_Previous').checked) {
269: document.getElementById('choosewasactive').style.display='block';
270: document.getElementById('choosewasacctext').innerHTML = '$wasacctext';
271: } else {
272: document.getElementById('choosewasactive').style.display='none';
273: document.getElementById('choosewasacctext').innerHTML = '';
274: }
275: }
276: return;
277: }
278:
279: ENDTOGGJS
280: }
1.28 raeburn 281: if ($env{'form.currcat_0'} eq 'instcode::0') {
282: $numtitles = &instcode_course_selector($r,$codedom,$formname,$domdesc,
1.82 raeburn 283: $catlinks,$catjs,\@codetitles,$cattype);
1.28 raeburn 284: if ($env{'form.state'} eq 'listing') {
1.63 raeburn 285: $r->print(&print_course_listing($codedom,$numtitles,undef,undef,undef,
286: \@codetitles));
1.28 raeburn 287: }
288: } else {
289: my (%add_entries);
1.50 raeburn 290: my ($currdepth,$deeper) = &get_depth_values();
1.46 raeburn 291: if ($selitem) {
1.50 raeburn 292: my $alert = &mt('Choose a subcategory to display');
293: if (!$deeper) {
294: $alert = &mt('Choose a category to display');
295: }
1.46 raeburn 296: $catjs .= <<ENDJS;
297: function check_selected() {
298: if (document.coursecats.$selitem.options[document.coursecats.$selitem.selectedIndex].value == "") {
1.50 raeburn 299: alert('$alert');
1.46 raeburn 300: return false;
301: }
302: }
303: ENDJS
304: }
1.28 raeburn 305: $catjs = '<script type="text/javascript">'."\n".$catjs."\n".'</script>';
1.82 raeburn 306: &cat_header($r,$codedom,$catjs,\%add_entries,$catlinks,undef,$cattype);
1.28 raeburn 307: if ($env{'form.currcat_0'} ne '') {
1.33 raeburn 308: $r->print('<form name="'.$formname.
309: '" method="post" action="/adm/coursecatalog">'.
1.36 raeburn 310: &additional_filters($codedom,$has_subcats)."\n");
1.33 raeburn 311: $r->print('<input type="hidden" name="catalog_maxdepth" value="'.
312: $deeper.'" />'."\n");
313: for (my $i=0; $i<$deeper; $i++) {
314: $r->print('<input type="hidden" name="currcat_'.$i.'" value="'.$env{'form.currcat_'.$i}.'" />'."\n");
315: }
1.57 raeburn 316: my $display_button;
317: if ($env{'form.currcat_0'} eq 'communities::0') {
318: $display_button = &mt('Display communities');
319: } else {
320: $display_button = &mt('Display courses');
321: }
1.33 raeburn 322: $r->print('<input type="hidden" name="coursenum" value="" />'."\n".
323: '<input type="hidden" name="sortby" value="" />'."\n".
324: '<input type="hidden" name="state" value="listing" />'."\n".
325: '<input type="hidden" name="showdom" value="'.
326: $env{'form.showdom'}.'" />'.
327: '<input type="submit" name="catalogfilter" value="'.
1.57 raeburn 328: $display_button.'" /></form><br /><br />');
1.33 raeburn 329: }
330: if ($env{'form.state'} eq 'listing') {
1.63 raeburn 331: $r->print(&print_course_listing($codedom,undef,\@trails,\%allitems,$subcats,\@codetitles));
1.28 raeburn 332: }
1.18 raeburn 333: }
1.7 raeburn 334: }
1.32 raeburn 335: $r->print('<br />'.&Apache::loncommon::end_page());
1.7 raeburn 336: return OK;
337: }
338:
339: sub course_details {
1.63 raeburn 340: my ($r,$codedom,$formname,$domdesc,$trails,$allitems,$codetitles) = @_;
1.7 raeburn 341: my $output;
342: my %add_entries = (topmargin => "0",
343: marginheight => "0",);
1.40 raeburn 344: my $js = '<script type="text/javascript">'."\n".
1.41 raeburn 345: &courselink_javascript().'</script>'."\n";
1.7 raeburn 346: my $start_page =
1.56 bisitz 347: &Apache::loncommon::start_page('Course/Community Catalog',$js,
1.72 raeburn 348: {'add_entries' => \%add_entries, });
1.7 raeburn 349: $r->print($start_page);
1.19 raeburn 350: if ($env{'form.numtitles'} > 0) {
351: &Apache::lonhtmlcommon::add_breadcrumb
352: ({href=>"/adm/coursecatalog",
1.56 bisitz 353: text=>"Course/Community Catalog"});
1.19 raeburn 354: }
1.60 raeburn 355: my $brtextone = 'Course listing';
356: my $brtexttwo = 'Course details';
357: if ($env{'form.currcat_0'} eq 'communities::0') {
358: $brtextone = 'Community listing';
1.61 raeburn 359: $brtexttwo = 'Community details';
1.60 raeburn 360: }
1.7 raeburn 361: &Apache::lonhtmlcommon::add_breadcrumb
1.19 raeburn 362: ({href=>"javascript:document.$formname.submit()",
1.60 raeburn 363: text=>$brtextone},
364: {text=>$brtexttwo});
1.78 bisitz 365: $r->print(
366: &Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog').
367: '<h2>'.
368: (($env{'form.currcat_0'} eq 'communities::0') ?
369: &mt('Detailed community information:') :
370: &mt('Detailed course information:')).
371: '</h2>'.
372: &print_course_listing($codedom,undef,$trails,$allitems,undef,$codetitles).
373: '<br />'.
374: '<form name="'.$formname.'" method="post" action="/adm/coursecatalog">'.
375: &Apache::lonhtmlcommon::actionbox([
376: '<a href = "javascript:document.coursecatalog.submit()">'.
377: (($env{'form.currcat_0'} eq 'communities::0') ?
378: &mt('Back to community listing') : &mt('Back to course listing')).
379: '</a>'
380: ]).
381: &Apache::lonhtmlcommon::echo_form_input(['coursenum','catalogfilter',
382: 'showdetails','courseid']).
383: '</form>');
1.40 raeburn 384: return;
385: }
386:
1.82 raeburn 387: sub coursesearch {
388: my ($codedom,$domdesc,$uniquecode) = @_;
389: my %lt = &Apache::lonlocal::texthash (
390: crlk => 'Course look-up',
391: code => 'Code',
1.84 raeburn 392: ifyo => 'Enter the course code (six letters and numbers)',
1.82 raeburn 393: srch => 'Find course',
394: );
395: return <<"END";
396: <h3>$lt{'crlk'} ($domdesc)</h3>
397: $lt{'ifyo'}
398: <form name="searchbycode" method="post" action="">
399: <span class="LC_nobreak">
400: <input type="text" value="$uniquecode" size="6" name="uniquecode" />
401: <br />
402: <input type="submit" value="$lt{'srch'}" name="srch" /></span>
403: </form>
404: END
405: }
406:
1.41 raeburn 407: sub courselink_javascript {
1.40 raeburn 408: return <<"END";
409:
410: function ToSyllabus(cdom,cnum) {
411: if (cdom == '' || cdom == null) {
412: return;
413: }
414: if (cnum == '' || cnum == null) {
415: return;
416: }
1.41 raeburn 417: document.linklaunch.action = "/public/"+cdom+"/"+cnum+"/syllabus";
418: document.linklaunch.submit();
419: }
420:
421: function ToSelfenroll(courseid) {
422: if (courseid == '') {
423: return;
424: }
425: document.linklaunch.action = "/adm/selfenroll";
426: document.linklaunch.courseid.value = courseid;
427: document.linklaunch.submit();
1.40 raeburn 428: }
429:
430: END
1.7 raeburn 431: }
432:
1.28 raeburn 433: sub instcode_course_selector {
1.82 raeburn 434: my ($r,$codedom,$formname,$domdesc,$catlinks,$catjs,$codetitles,$cattype) = @_;
1.1 raeburn 435: my %coursecodes = ();
436: my %codes = ();
437: my %cat_titles = ();
438: my %cat_order = ();
1.6 raeburn 439: my %cat_items;
1.1 raeburn 440: my $caller = 'global';
441: my $format_reply;
1.30 raeburn 442: my %add_entries = (topmargin => "0",
443: marginheight => "0",);
1.51 raeburn 444: my ($jscript,$totcodes,$numtitles,$lasttitle) =
445: &Apache::courseclassifier::instcode_selectors_data($codedom,$formname,
1.63 raeburn 446: \%cat_items,$codetitles,\%cat_titles,\%cat_order);
1.80 bisitz 447: my $js = '<script type="text/javascript">'."\n".
1.79 raeburn 448: '// <![CDATA['."\n".
449: "$jscript\n$catjs\n".
450: '// ]]>'."\n".
451: '</script>';
1.51 raeburn 452: if ($totcodes) {
1.18 raeburn 453: if (($env{'form.state'} eq 'listing') && ($numtitles > 0)) {
1.72 raeburn 454: $add_entries{'onLoad'} = 'setElements();';
455: }
456: if (&user_is_dc($codedom)) {
457: $add_entries{'onLoad'} .= ' toggleStatuses();toggleWasActive();'
1.7 raeburn 458: }
1.82 raeburn 459: &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles,$cattype);
1.28 raeburn 460: my $cat_maxdepth = $env{'form.catalog_maxdepth'};
461: $r->print('<form name="'.$formname.'" method="post" action="/adm/coursecatalog">'.
1.32 raeburn 462: '<input type="hidden" name="catalog_maxdepth" value="'.$cat_maxdepth.'" />'."\n".
463: '<input type="hidden" name="showdom" value="'.$env{'form.showdom'}.'" />'."\n".
464: '<input type="hidden" name="currcat_0" value="instcode::0" />'.
1.33 raeburn 465: &additional_filters($codedom));
1.1 raeburn 466: if ($numtitles > 0) {
1.51 raeburn 467: $r->print('<b>'.&mt('Choose which course(s) to list.').'</b><br />'.
468: &Apache::courseclassifier::build_instcode_selectors($numtitles,
1.63 raeburn 469: $lasttitle,\%cat_items,$codetitles,\%cat_titles,\%cat_order));
1.18 raeburn 470: }
1.33 raeburn 471: $r->print('<input type="hidden" name="coursenum" value="" />'."\n".
472: '<input type="hidden" name="sortby" value="" />'."\n".
473: '<input type="hidden" name="state" value="listing" />'."\n".
474: '<input type="submit" name="catalogfilter" value="'.
475: &mt('Display courses').'" />'.
476: '<input type="hidden" name="numtitles" value="'.$numtitles.
1.37 raeburn 477: '" /></form><br /><br />');
1.5 raeburn 478: } else {
1.81 raeburn 479: $js = '<script type="text/javascript">'."\n".
480: '// <![CDATA['."\n".
481: "$catjs\n".
482: '// ]]>'."\n".
483: '</script>';
1.82 raeburn 484: &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles,$cattype);
1.30 raeburn 485: my $cat_maxdepth = $env{'form.catalog_maxdepth'};
486: $r->print('<form name="'.$formname.'" method="post" action="/adm/coursecatalog">'.
487: '<input type="hidden" name="catalog_maxdepth" value="'.$cat_maxdepth.'" />'.
488: '<input type="hidden" name="showdom" value="'.$env{'form.showdom'}.'" />'.
489: '<input type="hidden" name="currcat_0" value="instcode::0" />');
490: $r->print('<br />'.&mt('No official courses to display for [_1].',$domdesc).'</form>');
1.1 raeburn 491: }
1.18 raeburn 492: return $numtitles;
1.1 raeburn 493: }
494:
1.28 raeburn 495: sub cat_header {
1.82 raeburn 496: my ($r,$codedom,$js,$add_entries,$catlinks,$numtitles,$cattype) = @_;
1.28 raeburn 497: my $start_page =
1.72 raeburn 498: &Apache::loncommon::start_page('Course/Community Catalog',$js,
1.59 droeschl 499: { 'add_entries' => $add_entries, });
1.28 raeburn 500: $r->print($start_page);
1.60 raeburn 501: my $brtext = 'Course listing';
502: if ($env{'form.currcat_0'} eq 'communities::0') {
503: $brtext = 'Community listing';
504: }
1.28 raeburn 505: if ($env{'form.state'} eq 'listing') {
506: if ($numtitles > 0) {
507: &Apache::lonhtmlcommon::add_breadcrumb
508: ({href=>"/adm/coursecatalog",
1.56 bisitz 509: text=>"Course/Community Catalog"},
1.60 raeburn 510: {text=>$brtext});
1.28 raeburn 511: } else {
512: &Apache::lonhtmlcommon::add_breadcrumb
1.60 raeburn 513: ({text=>$brtext});
1.28 raeburn 514: }
515: } else {
516: &Apache::lonhtmlcommon::add_breadcrumb
517: ({href=>"/adm/coursecatalog",
1.56 bisitz 518: text=>"Course/Community Catalog"});
1.28 raeburn 519: }
1.55 raeburn 520: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog'));
1.82 raeburn 521: if ($cattype eq 'std') {
522: my $onchange = 'this.form.submit()';
523: $r->print('<form name="coursecatdom" method="post" action="/adm/coursecatalog">'.
524: '<table border="0"><tr><td><b>'.&mt('Domain:').'</b></td><td>'.
525: &Apache::loncommon::select_dom_form($codedom,'showdom','',1,$onchange));
526: if (!$onchange) {
1.47 raeburn 527: $r->print(' <input type="submit" name="godom" value="'.&mt('Change').'" />');
1.82 raeburn 528: }
529: $r->print('</td></tr></table></form>');
1.47 raeburn 530: }
1.82 raeburn 531: $r->print('<form name="coursecats" method="post" action="/adm/coursecatalog"'.
1.48 raeburn 532: ' onsubmit="return check_selected();">'.
1.34 raeburn 533: '<table border="0"><tr>'.$catlinks.'</tr></table></form>');
1.28 raeburn 534: return;
535: }
536:
537: sub category_breadcrumbs {
1.35 raeburn 538: my ($dom,@cats) = @_;
1.44 raeburn 539: my $crumbsymbol = ' ▶ ';
1.33 raeburn 540: my ($currdepth,$deeper) = &get_depth_values();
1.57 raeburn 541: my $currcat_str =
542: '<input type="hidden" name="catalog_maxdepth" value="'.$deeper.'" />'.
543: '<input type="hidden" name="showdom" value="'.$dom.'" />';
1.58 raeburn 544: my $catlinks = '<td valign="top"><b>'.&mt('Catalog:').'</b></td><td><table><tr><td>';
1.36 raeburn 545: my $has_subcats;
1.46 raeburn 546: my $selitem;
1.58 raeburn 547: if (ref($cats[0]) eq 'ARRAY') {
548: if (@{$cats[0]} == 0) {
549: $catlinks .= &mt('No categories defined in this domain');
550: } elsif (@{$cats[0]} == 1) {
551: if ($cats[0][0] eq 'instcode') {
552: $catlinks .= &mt('Official courses (with institutional codes)');
553: $env{'form.currcat_0'} = 'instcode::0';
554: } elsif ($cats[0][0] eq 'communities') {
555: $catlinks .= &mt('Communities');
556: $env{'form.currcat_0'} = 'communities::0';
557: } else {
558: my $name = $cats[0][0];
559: my $item = &escape($name).'::0';
560: $catlinks .= $name;
561: $env{'form.currcat_0'} = $item;
1.46 raeburn 562: }
1.58 raeburn 563: $currcat_str .= '<input type="hidden" name="currcat_0" value="'.$env{'form.currcat_0'}.'" />';
1.28 raeburn 564: } else {
1.58 raeburn 565: $catlinks .= &main_category_selector(@cats);
566: if (($env{'form.currcat_0'} ne '') &&
567: ($env{'form.currcat_0'} ne 'instcode::0')) {
568: $catlinks .= $crumbsymbol;
569: }
570: }
571: } else {
572: $catlinks .= &mt('Official courses (with institutional codes)');
573: $env{'form.currcat_0'} = 'instcode::0';
574: $currcat_str .= '<input type="hidden" name="currcat_0" value="'.$env{'form.currcat_0'}.'" />';
575: }
576: if ($deeper) {
577: for (my $i=1; $i<=$deeper; $i++) {
578: my $shallower = $i-1;
579: next if ($shallower == 0);
1.28 raeburn 580: my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$env{'form.currcat_'.$shallower});
1.58 raeburn 581: if ($cat ne '') {
582: $catlinks .= '<td valign="top">'.
583: '<select name="currcat_'.$shallower.'" onchange="'.
584: 'setCatDepth('."'$shallower'".');this.form.submit();">';
585: if (ref($cats[$shallower]{$container}) eq 'ARRAY') {
586: $catlinks .= '<option value="">'.&mt('De-select').'</option>';
587: for (my $j=0; $j<@{$cats[$shallower]{$container}}; $j++) {
588: my $name = $cats[$shallower]{$container}[$j];
1.65 raeburn 589: my $item = &escape($name).':'.&escape($container).':'.$shallower;
1.58 raeburn 590: my $selected = '';
591: if ($item eq $env{'form.currcat_'.$shallower}) {
592: $selected = ' selected="selected"';
593: }
594: $catlinks .=
595: '<option value="'.$item.'"'.$selected.'>'.$name.'</option>';
1.28 raeburn 596: }
597: }
1.58 raeburn 598: $catlinks .= '</select>';
1.28 raeburn 599: }
1.58 raeburn 600: unless ($i == $deeper) {
601: $catlinks .= $crumbsymbol;
602: }
1.28 raeburn 603: }
1.29 raeburn 604: my ($cat,$container,$depth);
605: if ($env{'form.currcat_'.$currdepth} eq '') {
606: my $shallower = $currdepth - 1;
607: ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$env{'form.currcat_'.$shallower});
608: } else {
609: ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$env{'form.currcat_'.$currdepth});
610: }
1.58 raeburn 611: my $deeperlevel = $depth +1;
612: if (ref($cats[$deeperlevel]{$cat}) eq 'ARRAY') {
1.36 raeburn 613: $has_subcats = 1;
1.46 raeburn 614: my $buttontext = &mt('Show subcategories');
1.58 raeburn 615: my $selitem = 'currcat_'.$deeperlevel;
616: $catlinks .= ' <select name="'.$selitem.'" onchange="this.form.submit()">';
617: if (@{$cats[$deeperlevel]{$cat}}) {
1.46 raeburn 618: $catlinks .= '<option value="" selected="selected">'.
1.58 raeburn 619: &mt('Subcategory ...').'</option>';
1.46 raeburn 620: }
1.58 raeburn 621: for (my $k=0; $k<@{$cats[$deeperlevel]{$cat}}; $k++) {
622: my $name = $cats[$deeperlevel]{$cat}[$k];
623: my $item = &escape($name).':'.&escape($cat).':'.$deeperlevel;
1.28 raeburn 624: $catlinks .= '<option value="'.$item.'">'.$name.'</option>'."\n";
625: }
1.58 raeburn 626: $catlinks .= '</select>'."\n";
1.46 raeburn 627: } elsif ($cat ne 'instcode') {
628: $catlinks .= ' '.&mt('(No subcategories)');
1.28 raeburn 629: }
1.58 raeburn 630: } else {
631: $selitem = 'currcat_0';
1.28 raeburn 632: }
633: $catlinks .= $currcat_str.'</td></tr></table></td>';
1.46 raeburn 634: return ($catlinks,$has_subcats,$selitem);
1.28 raeburn 635: }
636:
1.58 raeburn 637: sub main_category_selector {
638: my (@cats) = @_;
639: my $maincatlinks = '<select name="currcat_0" onchange="setCatDepth('."'0'".');this.form.submit();">'."\n";
640: if (ref($cats[0]) eq 'ARRAY') {
641: if (@{$cats[0]} > 1) {
642: my $selected = '';
643: if ($env{'form.currcat_0'} eq '') {
644: $selected = ' selected="selected"';
645: }
646: $maincatlinks .=
647: '<option value=""'.$selected.'>'.&mt('Select').'</option>'."\n";
648: }
649: for (my $i=0; $i<@{$cats[0]}; $i++) {
650: my $name = $cats[0][$i];
651: my $item = &escape($name).'::0';
652: my $selected;
653: if ($env{'form.currcat_0'} eq $item) {
654: $selected = ' selected="selected"';
655: }
656: $maincatlinks .= '<option value="'.$item.'"'.$selected.'>';
657: if ($name eq 'instcode') {
658: $maincatlinks .= &mt('Official courses (with institutional codes)');
659: } elsif ($name eq 'communities') {
660: $maincatlinks .= &mt('Communities');
661: } else {
662: $maincatlinks .= $name;
663: }
664: $maincatlinks .= '</option>'."\n";
665: }
666: $maincatlinks .= '</select>'."\n";
667: }
668: return $maincatlinks;
669: }
670:
1.33 raeburn 671: sub get_depth_values {
672: my $currdepth = 0;
673: my $deeper = 0;
674: if ($env{'form.catalog_maxdepth'} ne '') {
675: $currdepth = $env{'form.catalog_maxdepth'};
676: if ($env{'form.currcat_'.$currdepth} eq '') {
677: $deeper = $currdepth;
678: } else {
679: $deeper = $currdepth + 1;
680: }
681: }
682: return ($currdepth,$deeper);
683: }
684:
685: sub additional_filters {
1.36 raeburn 686: my ($codedom,$has_subcats) = @_;
1.72 raeburn 687: my $is_dc = &user_is_dc($codedom);
688: my $output = '<div class="LC_left_float">';
689: if ($is_dc) {
690: $output .= '<fieldset><legend>'.&mt('Options').'</legend>';
691: }
692: $output .= '<table><tr><td valign="top">';
693: if (($env{'form.currcat_0'} ne 'instcode::0') &&
1.36 raeburn 694: ($env{'form.currcat_0'} ne '') && ($has_subcats)) {
695: my $include_subcat_status;
696: if ($env{'form.withsubcats'}) {
697: $include_subcat_status = 'checked="checked" ';
698: }
699: my $counter = $env{'form.catalog_maxdepth'};
700: if ($counter > 0) {
701: if ($env{'form.state'} eq 'listing') {
702: $counter --;
703: } elsif ($env{'form.currcat_'.$counter} eq '') {
704: $counter --;
705: }
706: }
707: my ($catname) = split(/:/,$env{'form.currcat_'.$counter});
708: if ($catname ne '') {
1.72 raeburn 709: $output .= '<span class="LC_nobreak"><label>'.
1.36 raeburn 710: '<input type="checkbox" name="withsubcats" value="1" '.
711: $include_subcat_status.'/>'.
1.38 raeburn 712: &mt('Include subcategories within "[_1]"',
1.72 raeburn 713: &unescape($catname)).'</label></span><br />';
1.36 raeburn 714: }
715: }
1.33 raeburn 716: my $show_selfenroll_status;
717: if ($env{'form.showselfenroll'}) {
718: $show_selfenroll_status = 'checked="checked" ';
719: }
1.57 raeburn 720: my $selfenroll_text;
721: if ($env{'form.currcat_0'} eq 'communities::0') {
1.69 raeburn 722: $selfenroll_text = &mt('Only show communities which currently allow self-enrollment (or will allow it in the future)');
1.57 raeburn 723: } else {
1.69 raeburn 724: $selfenroll_text = &mt('Only show courses which currently allow self-enrollment (or will allow it in the future)');
1.57 raeburn 725: }
1.72 raeburn 726: $output .= '<span class="LC_nobreak">'.
1.36 raeburn 727: '<label><input type="checkbox" name="showselfenroll" value="1" '.
1.57 raeburn 728: $show_selfenroll_status.'/>'.$selfenroll_text.
1.72 raeburn 729: '</label></span><br />';
730: if ($is_dc) {
731: my ($titlesref,$orderref) = &get_statustitles('filters');
1.33 raeburn 732: my $showdetails_status;
733: if ($env{'form.showdetails'}) {
734: $showdetails_status = 'checked="checked" ';
735: }
736: my $showhidden_status;
737: if ($env{'form.showhidden'}) {
1.72 raeburn 738: $showhidden_status = 'checked="checked" ';
1.33 raeburn 739: }
1.72 raeburn 740: my @currstatuses = &Apache::loncommon::get_env_multiple('form.showcounts');
1.33 raeburn 741: my $dc_title = &Apache::lonnet::plaintext('dc');
1.72 raeburn 742: my ($details_text,$hidden_text,$statusdisplay,$cellborder);
743: my $wasactivedisplay = 'none';
744: if ($env{'form.showdetails'}) {
745: $statusdisplay = 'block';
746: $cellborder = 'border-left: 1px solid;';
747: if (grep(/^Previous$/,@currstatuses)) {
748: $wasactivedisplay = 'block';
749: }
750: } else {
751: $statusdisplay = 'none';
752: $cellborder = 'border-left: 0px';
753: }
1.57 raeburn 754: if ($env{'form.currcat_0'} eq 'communities::0') {
755: $details_text = &mt('Show full details for each community ([_1] only)',$dc_title);
756: $hidden_text = &mt('Include communities set to be hidden from catalog ([_1] only)',$dc_title);
757: } else {
758: $details_text = &mt('Show full details for each course ([_1] only)',$dc_title);
759: $hidden_text = &mt('Include courses set to be hidden from catalog ([_1] only)',$dc_title);
760: }
1.72 raeburn 761: $output .= '<span class="LC_nobreak">'.
1.33 raeburn 762: '<label><input type="checkbox" name="showhidden" value="1" '.
1.57 raeburn 763: $showhidden_status.'/>'.$hidden_text.
1.72 raeburn 764: '</label></span><br />'."\n".
765: '<span class="LC_nobreak">'.
766: '<label><input type="checkbox" name="showdetails" value="1" '.
767: $showdetails_status.'onclick="toggleStatuses();" />'.
768: $details_text.'</label></span></td>'."\n".
769: '<td id="statuscell" valign="top" style="'.$cellborder.'">'.
770: '<div id="statuschoice" style="display:'.$statusdisplay.'">';
771: if (ref($orderref) eq 'ARRAY') {
772: if (@{$orderref} > 0) {
773: foreach my $type (@{$orderref}) {
774: my $checked;
775: if (grep(/^\Q$type\E$/,@currstatuses)) {
776: $checked = ' checked="checked"';
777: }
778: my $title;
779: if (ref($titlesref) eq 'HASH') {
780: $title = $titlesref->{$type};
781: }
782: unless ($title) {
783: $title = &mt($type);
784: }
785: my $onclick;
786: if ($type eq 'Previous') {
787: $onclick = ' onclick="toggleWasActive();"';
788: }
789: $output .= '<span class="LC_nobreak">'.
790: '<label><input type="checkbox" id="counts_'.$type.'"'.
791: ' name="showcounts" value="'.$type.'"'.$checked.$onclick.
792: ' />'.$title.'</label></span>';
793: if ($type eq 'Previous') {
794: my %milestonetext = &Apache::lonlocal::texthash (
1.74 raeburn 795: accessend => 'immediately prior to default end access date',
796: enrollend => 'immediately prior to end date for auto-enrollment',
797: date => 'immediately prior to specific date:',
1.72 raeburn 798: );
799: my @statuses = &Apache::loncommon::get_env_multiple('form.showcounts');
1.77 raeburn 800: $output .= '<span id="choosewasacctext" class="LC_nobreak">';
1.72 raeburn 801: if ($checked) {
802: $output .= &get_wasactive_text();
803: }
804: $output .= '</span>'.
805: '<div id="choosewasactive" style="display:'.$wasactivedisplay.'">'.
806: '<table>';
807: my @milestones = ('accessend');
808: if (&Apache::lonnet::auto_run(undef,$codedom)) {
809: push(@milestones,'enrollend');
810: }
811: push(@milestones,'date');
812: foreach my $item (@milestones) {
813: my $checked;
814: if ($env{'form.state'} eq 'listing') {
815: if ($env{'form.wasactive'} eq $item) {
816: $checked = ' checked="checked"';
817: }
818: } elsif ($item eq 'accessend') {
819: $checked = ' checked="checked"';
820: }
821: $output .=
822: '<tr><td width="10"> </td><td>'.
823: '<span class="LC_nobreak"><label>'.
824: '<input type="radio" value="'.$item.'" name="wasactive"'.$checked.' />'.
825: $milestonetext{$item}.'</label></span>';
826: if ($item eq 'date') {
827: my $wasactiveon;
828: if (grep(/^Previous$/,@currstatuses)) {
829: $wasactiveon =
830: &Apache::lonhtmlcommon::get_date_from_form('wasactiveon');
831: } else {
832: $wasactiveon = 'now';
833: }
834: $output .= ' '.
835: &Apache::lonhtmlcommon::date_setter('coursecatalog',
836: 'wasactiveon',
837: $wasactiveon,
838: '','','',1,'',
839: '','',1);
840: }
841: $output .= '</td></tr>';
842: }
843: $output .= '</table></div>';
844: }
845: $output .= '<br />';
846: }
847: }
848: }
849: $output .= '</div></td>';
850: } else {
851: $output .= '</td>';
1.33 raeburn 852: }
1.72 raeburn 853: $output .= '</tr></table></fieldset></div>'.
854: '<div style="clear:both;margin:0;"></div>';
1.33 raeburn 855: return $output;
856: }
857:
1.16 raeburn 858: sub user_is_dc {
859: my ($codedom) = @_;
860: if (exists($env{'user.role.dc./'.$codedom.'/'})) {
861: my $livedc = 1;
862: my $now = time;
863: my ($start,$end)=split(/\./,$env{'user.role.dc./'.$codedom.'/'});
864: if ($start && $start>$now) { $livedc = 0; }
865: if ($end && $end <$now) { $livedc = 0; }
866: return $livedc;
867: }
868: return;
869: }
1.7 raeburn 870:
1.72 raeburn 871: sub get_statustitles {
872: my ($caller) = @_;
873: my @status_order = ('Active','Future','Previous');
874: my %status_title;
875: if ($caller eq 'filters') {
876: %status_title = &Apache::lonlocal::texthash(
877: Previous => 'Show count for past access',
878: Active => 'Show count for current student access',
879: Future => 'Show count for future student access',
880: );
881: if ($env{'form.currcat_0'} eq 'communities::0') {
882: $status_title{'Active'} = 'Show count for current member access';
883: $status_title{'Future'} = 'Show count for future member access';
884: }
885: } else {
886: %status_title = &Apache::lonlocal::texthash(
887: Previous => 'Previous access',
888: Active => 'Current access',
889: Future => 'Future access',
890: );
891: }
892: return (\%status_title,\@status_order);
893: }
894:
895: sub get_wasactive_text {
896: my $wasacctext = ' -- ';
897: if ($env{'form.currcat_0'} eq 'communities::0') {
1.74 raeburn 898: $wasacctext .= &mt('where member access status was current ...');
1.72 raeburn 899: } else {
1.74 raeburn 900: $wasacctext .= &mt('where student access status was current ...');
1.72 raeburn 901: }
902: return $wasacctext;
903: }
904:
1.28 raeburn 905: sub search_official_courselist {
1.63 raeburn 906: my ($domain,$numtitles,$codetitles) = @_;
907: my $instcode = &Apache::courseclassifier::instcode_search_str($domain,$numtitles,$codetitles);
1.32 raeburn 908: my $showhidden;
909: if (&user_is_dc($domain)) {
910: $showhidden = $env{'form.showhidden'};
911: }
912: my %courses =
913: &Apache::lonnet::courseiddump($domain,'.',1,$instcode,'.','.',undef,undef,
914: 'Course',1,$env{'form.showselfenroll'},undef,
915: $showhidden,'coursecatalog');
1.7 raeburn 916: return %courses;
917: }
918:
1.28 raeburn 919: sub search_courselist {
1.36 raeburn 920: my ($domain,$subcats) = @_;
1.28 raeburn 921: my $cat_maxdepth = $env{'form.catalog_maxdepth'};
922: my $filter = $env{'form.currcat_'.$cat_maxdepth};
1.29 raeburn 923: if (($filter eq '') && ($cat_maxdepth > 0)) {
924: my $shallower = $cat_maxdepth - 1;
925: $filter = $env{'form.currcat_'.$shallower};
926: }
1.28 raeburn 927: my %courses;
1.36 raeburn 928: my $filterstr;
1.28 raeburn 929: if ($filter ne '') {
1.36 raeburn 930: if ($env{'form.withsubcats'}) {
931: if (ref($subcats) eq 'HASH') {
932: if (ref($subcats->{$filter}) eq 'ARRAY') {
933: $filterstr = join('&',@{$subcats->{$filter}});
934: if ($filterstr ne '') {
935: $filterstr = $filter.'&'.$filterstr;
936: }
937: } else {
938: $filterstr = $filter;
939: }
940: } else {
941: $filterstr = $filter;
942: }
943: } else {
944: $filterstr = $filter;
945: }
1.57 raeburn 946: my ($showhidden,$typefilter);
1.32 raeburn 947: if (&user_is_dc($domain)) {
948: $showhidden = $env{'form.showhidden'};
949: }
1.57 raeburn 950: if ($env{'form.currcat_0'} eq 'communities::0') {
951: $typefilter = 'Community';
952: } else {
953: $typefilter = '.';
954: }
1.32 raeburn 955: %courses =
956: &Apache::lonnet::courseiddump($domain,'.',1,'.','.','.',undef,undef,
1.57 raeburn 957: $typefilter,1,$env{'form.showselfenroll'},
1.36 raeburn 958: $filterstr,$showhidden,'coursecatalog');
1.28 raeburn 959: }
960: return %courses;
961: }
1.6 raeburn 962:
1.1 raeburn 963: sub print_course_listing {
1.63 raeburn 964: my ($domain,$numtitles,$trails,$allitems,$subcats,$codetitles) = @_;
1.1 raeburn 965: my $output;
1.7 raeburn 966: my %courses;
1.15 raeburn 967: my $knownuser = &user_is_known();
1.16 raeburn 968: my $details = $env{'form.coursenum'};
969: if (&user_is_dc($domain)) {
970: if ($env{'form.showdetails'}) {
971: $details = 1;
972: }
973: }
1.7 raeburn 974: if ($env{'form.coursenum'} ne '') {
975: %courses = &Apache::lonnet::courseiddump($domain,'.',1,'.','.',
976: $env{'form.coursenum'},
1.33 raeburn 977: undef,undef,'.',1);
1.7 raeburn 978: if (keys(%courses) == 0) {
1.78 bisitz 979: $output = '<p class="LC_error">';
1.60 raeburn 980: if ($env{'form.currcat_0'} eq 'communities::0') {
981: $output .= &mt('The courseID provided does not match a community in this domain.');
982: } else {
983: $output .= &mt('The courseID provided does not match a course in this domain.');
984: }
1.78 bisitz 985: $output .= '</p>';
1.7 raeburn 986: return $output;
987: }
1.6 raeburn 988: } else {
1.28 raeburn 989: if ($env{'form.currcat_0'} eq 'instcode::0') {
1.63 raeburn 990: %courses = &search_official_courselist($domain,$numtitles,$codetitles);
1.28 raeburn 991: } else {
1.36 raeburn 992: %courses = &search_courselist($domain,$subcats);
1.28 raeburn 993: }
1.7 raeburn 994: if (keys(%courses) == 0) {
1.78 bisitz 995: $output = '<p class="LC_info">';
1.57 raeburn 996: if ($env{'form.currcat_0'} eq 'communities::0') {
1.78 bisitz 997: $output .= &mt('No communities match the criteria you selected.');
1.57 raeburn 998: } else {
1.78 bisitz 999: $output .= &mt('No courses match the criteria you selected.');
1.57 raeburn 1000: }
1.78 bisitz 1001: $output .= '</p>';
1.7 raeburn 1002: return $output;
1003: }
1.32 raeburn 1004: if (($knownuser) && (!$env{'form.showdetails'}) && (!&user_is_dc($domain))) {
1.31 bisitz 1005: $output = '<b>'.&mt('Note for students:').'</b> '
1006: .&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.')
1007: .'<br /><br />';
1.8 raeburn 1008: }
1.7 raeburn 1009: }
1.27 raeburn 1010: my $now = time;
1.72 raeburn 1011: $output .= &construct_data_table($knownuser,$domain,\%courses,$details,undef,
1.82 raeburn 1012: $now,$trails,$allitems);
1.41 raeburn 1013: $output .= "\n".'<form name="linklaunch" method="post" action="">'.
1.40 raeburn 1014: '<input type="hidden" name="backto" value="coursecatalog" />'.
1.41 raeburn 1015: '<input type="hidden" name="courseid" value="" />'.
1016: &Apache::lonhtmlcommon::echo_form_input(['catalogfilter','courseid']).'</form>';
1.15 raeburn 1017: return $output;
1018: }
1019:
1020: sub construct_data_table {
1.82 raeburn 1021: my ($knownuser,$domain,$courses,$details,$usersections,$now,$trails,$allitems) = @_;
1.7 raeburn 1022: my %sortname;
1.16 raeburn 1023: if (($details eq '') || ($env{'form.showdetails'})) {
1.7 raeburn 1024: $sortname{'Code'} = 'code';
1.35 raeburn 1025: $sortname{'Categories'} = 'cats';
1.7 raeburn 1026: $sortname{'Title'} = 'title';
1.70 raeburn 1027: $sortname{'Owner & Co-owner(s)'} = 'owner';
1.7 raeburn 1028: }
1.15 raeburn 1029: my $output = &Apache::loncommon::start_data_table().
1030: &Apache::loncommon::start_data_table_header_row();
1.35 raeburn 1031: my @coltitles = ('Count');
1032: if ($env{'form.currcat_0'} eq 'instcode::0') {
1033: push(@coltitles,'Code');
1034: } else {
1035: push(@coltitles,'Categories');
1036: }
1.70 raeburn 1037: push(@coltitles,('Sections','Crosslisted','Title','Owner & Co-owner(s)'));
1.15 raeburn 1038: if (ref($usersections) eq 'HASH') {
1039: $coltitles[1] = 'Your Section';
1040: }
1.7 raeburn 1041: foreach my $item (@coltitles) {
1042: $output .= '<th>';
1043: if (defined($sortname{$item})) {
1044: $output .= '<a href="javascript:changeSort('."'$sortname{$item}'".')">'.&mt($item).'</a>';
1.24 raeburn 1045: } elsif ($item eq 'Count') {
1046: $output .= ' ';
1.7 raeburn 1047: } else {
1048: $output .= &mt($item);
1049: }
1050: $output .= '</th>';
1.1 raeburn 1051: }
1.72 raeburn 1052: my (@fields,%fieldtitles,$wasactiveon);
1.15 raeburn 1053: if ($knownuser) {
1054: if ($details) {
1.60 raeburn 1055: if ($env{'form.currcat_0'} eq 'communities::0') {
1.72 raeburn 1056: $output .= '<th>'.&mt('Default Access Dates for Members').'</th>'.
1057: '<th>'.&mt('Member Counts').'</th>';
1.60 raeburn 1058: } else {
1059: $output .=
1060: '<th>'.&mt('Default Access Dates for Students').'</th>'.
1061: '<th>'.&mt('Student Counts').'</th>'.
1062: '<th>'.&mt('Auto-enrollment of[_1]registered students','<br />').'</th>';
1063: }
1.72 raeburn 1064: my ($titlesref,$orderref) = &get_statustitles();
1065: my @statuses;
1066: if (&user_is_dc($domain)) {
1067: @statuses = &Apache::loncommon::get_env_multiple('form.showcounts');
1068: if (grep(/^Previous$/,@statuses)) {
1069: if ($env{'form.wasactive'} eq 'date') {
1070: $wasactiveon =
1071: &Apache::lonhtmlcommon::get_date_from_form('wasactiveon');
1072: } else {
1073: $wasactiveon = $env{'form.wasactive'};
1074: }
1075: }
1076: if (ref($orderref) eq 'ARRAY') {
1077: foreach my $status (@{$orderref}) {
1078: if (grep(/^\Q$status\E$/,@statuses)) {
1079: push(@fields,$status);
1080: }
1081: }
1082: }
1083: } else {
1084: @fields = ('Active','Future');
1085: }
1086: foreach my $status (@fields) {
1087: my $title;
1088: if (ref($titlesref) eq 'HASH') {
1089: $title = $titlesref->{$status};
1090: }
1091: unless ($title) {
1092: $title = &mt($status);
1093: }
1094: $fieldtitles{$status} = $title;
1095: }
1.15 raeburn 1096: } else {
1.27 raeburn 1097: $output .= '<th>'.&mt('Details').'</th>';
1.8 raeburn 1098: }
1.1 raeburn 1099: }
1.27 raeburn 1100: $output .= '<th>'.&mt('Self-enroll (if permitted)').'</th>';
1.7 raeburn 1101: &Apache::loncommon::end_data_table_header_row();
1.73 raeburn 1102: my (%numbers,%creditsum);
1.76 raeburn 1103: my ($showcredits,$defofficial,$defunofficial,$deftextbook);
1.73 raeburn 1104: my %domdefaults = &Apache::lonnet::get_domain_defaults($domain);
1105: unless ($env{'form.currcat_0'} eq 'communities::0') {
1.76 raeburn 1106: if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'} || $domdefaults{'textbookcredits'}) {
1.73 raeburn 1107: $showcredits = 1;
1108: $defofficial = $domdefaults{'officialcredits'};
1.76 raeburn 1109: $defunofficial = $domdefaults{'unofficialcredits'};
1110: $deftextbook = $domdefaults{'textbookcredits'};
1.73 raeburn 1111: }
1112: }
1.72 raeburn 1113: my %courseinfo = &build_courseinfo_hash($courses,$knownuser,$domain,$details,
1114: $usersections,\@fields,\%fieldtitles,
1.73 raeburn 1115: $wasactiveon,\%numbers,\%creditsum,
1.76 raeburn 1116: $showcredits,$defofficial,$defunofficial,$deftextbook);
1.7 raeburn 1117: my %Sortby;
1.15 raeburn 1118: foreach my $course (sort(keys(%{$courses}))) {
1.7 raeburn 1119: if ($env{'form.sortby'} eq 'code') {
1120: push(@{$Sortby{$courseinfo{$course}{'code'}}},$course);
1.35 raeburn 1121: } elsif ($env{'form.sortby'} eq 'cats') {
1122: push(@{$Sortby{$courseinfo{$course}{'categories'}}},$course);
1.7 raeburn 1123: } elsif ($env{'form.sortby'} eq 'owner') {
1.22 raeburn 1124: push(@{$Sortby{$courseinfo{$course}{'ownerlastnames'}}},$course);
1.7 raeburn 1125: } else {
1.25 raeburn 1126: my $clean_title = $courseinfo{$course}{'title'};
1127: $clean_title =~ s/\W+//g;
1128: if ($clean_title eq '') {
1129: $clean_title = $courseinfo{$course}{'title'};
1130: }
1131: push(@{$Sortby{$clean_title}},$course);
1.7 raeburn 1132: }
1133: }
1134: my @sorted_courses;
1.35 raeburn 1135: if (($env{'form.sortby'} eq 'code') || ($env{'form.sortby'} eq 'owner') ||
1136: ($env{'form.sortby'} eq 'cats')) {
1.7 raeburn 1137: @sorted_courses = sort(keys(%Sortby));
1.6 raeburn 1138: } else {
1.7 raeburn 1139: @sorted_courses = sort { lc($a) cmp lc($b) } (keys(%Sortby));
1.1 raeburn 1140: }
1.24 raeburn 1141: my $count = 1;
1.72 raeburn 1142: my $totalsec = 0;
1.7 raeburn 1143: foreach my $item (@sorted_courses) {
1144: foreach my $course (@{$Sortby{$item}}) {
1145: $output.=&Apache::loncommon::start_data_table_row();
1.35 raeburn 1146: $output.=&courseinfo_row($courseinfo{$course},$knownuser,$details,
1.72 raeburn 1147: \$count,$now,$course,$trails,$allitems,\%numbers);
1.7 raeburn 1148: $output.=&Apache::loncommon::end_data_table_row();
1149: }
1.1 raeburn 1150: }
1.72 raeburn 1151: if (($knownuser) && ($count > 1) && $env{'form.showdetails'}) {
1152: if (&user_is_dc($domain)) {
1153: my %lt = &Apache::lonlocal::texthash (
1154: 'Active' => 'Total current students',
1155: 'Future' => 'Total future students',
1156: 'Previous' => 'Total previous students',
1157: 'courses' => 'Total unique codes and courses without codes',
1158: 'sections' => 'Total sections',
1.73 raeburn 1159: 'xlists' => 'Total cross-listings',
1.72 raeburn 1160: );
1.73 raeburn 1161: if ($showcredits) {
1162: $lt{'cr_Active'} = &mt('Total current student credit hours');
1163: $lt{'cr_Future'} = &mt('Total future student credit hours');
1164: $lt{'cr_Previous'} = &mt('Total previous student credit hours');
1165: }
1.72 raeburn 1166: if ($env{'form.currcat_0'} eq 'communities::0') {
1167: $lt{'courses'} = &mt('Total communities');
1168: $lt{'Active'} = &mt('Total current members');
1169: $lt{'Future'} = &mt('Total future members');
1170: $lt{'Previous'} = &mt('Total previous members');
1.73 raeburn 1171: }
1172: my $colspan = 8;
1173: if ($showcredits) {
1174: $colspan = 4;
1175: }
1.72 raeburn 1176: $output .= '<tr class="LC_footer_row">'.
1177: '<td colspan="2"> </td>'.
1.73 raeburn 1178: '<td colspan="'.$colspan.'">'.
1.72 raeburn 1179: '<table border="0">';
1180: foreach my $item ('courses','sections','xlists') {
1181: $output .= '<tr>'.
1.73 raeburn 1182: '<td>'.$lt{$item}.'</td><td> </td>'.
1.72 raeburn 1183: '<td align="right">'.$numbers{$item}.'</td>'.
1184: '</tr>'."\n";
1185: }
1186: if (@fields > 0) {
1187: foreach my $status (@fields) {
1188: $output .= '<tr>'.
1.73 raeburn 1189: '<td>'.$lt{$status}.'</td><td> </td>'.
1.72 raeburn 1190: '<td align="right">'.$numbers{$status}.'</td>'.
1191: '</tr>'."\n";
1192: }
1193: }
1.73 raeburn 1194: $output .= '</table></td>';
1195: if ($showcredits) {
1196: $output .= '<td colspan="'.$colspan.'" valign="bottom"><table>';
1197: foreach my $status (@fields) {
1198: $output .= '<tr>'.
1199: '<td>'.$lt{'cr_'.$status}.'</td><td> </td>'.
1200: '<td align="right">'.$creditsum{$status}.'</td></tr>';
1201: }
1202: $output .= '</table></td></tr>';
1203: }
1.72 raeburn 1204: }
1205: }
1.7 raeburn 1206: $output .= &Apache::loncommon::end_data_table();
1207: return $output;
1208: }
1209:
1210: sub build_courseinfo_hash {
1.72 raeburn 1211: my ($courses,$knownuser,$domain,$details,$usersections,$fields,$fieldtitles,
1.73 raeburn 1212: $wasactiveon,$numbers,$creditsum,$showcredits,$defofficial,$defunofficial) = @_;
1.1 raeburn 1213: my %courseinfo;
1.7 raeburn 1214: my $now = time;
1.72 raeburn 1215: my $gettotals;
1216: if ((keys(%{$courses}) > 0) && (&user_is_dc($domain)) && ($details)) {
1217: $gettotals = 1;
1218: }
1.73 raeburn 1219: my (%uniquecodes,$nocodes,$defcreds);
1.15 raeburn 1220: foreach my $course (keys(%{$courses})) {
1.1 raeburn 1221: my $descr;
1.22 raeburn 1222: if (ref($courses->{$course}) eq 'HASH') {
1223: $descr = $courses->{$course}{'description'};
1.1 raeburn 1224: }
1225: my $cleandesc=&HTML::Entities::encode($descr,'<>&"');
1226: $cleandesc=~s/'/\\'/g;
1.10 raeburn 1227: $cleandesc =~ s/^\s+//;
1.1 raeburn 1228: my ($cdom,$cnum)=split(/\_/,$course);
1.39 raeburn 1229: my ($instcode,$singleowner,$ttype,$selfenroll_types,
1.35 raeburn 1230: $selfenroll_start,$selfenroll_end,@owners,%ownernames,$categories);
1.22 raeburn 1231: if (ref($courses->{$course}) eq 'HASH') {
1232: $descr = $courses->{$course}{'description'};
1.23 raeburn 1233: $instcode = $courses->{$course}{'inst_code'};
1.22 raeburn 1234: $singleowner = $courses->{$course}{'owner'};
1235: $ttype = $courses->{$course}{'type'};
1.27 raeburn 1236: $selfenroll_types = $courses->{$course}{'selfenroll_types'};
1237: $selfenroll_start = $courses->{$course}{'selfenroll_start_date'};
1238: $selfenroll_end = $courses->{$course}{'selfenroll_end_date'};
1.35 raeburn 1239: $categories = $courses->{$course}{'categories'};
1.22 raeburn 1240: push(@owners,$singleowner);
1.67 raeburn 1241: if ($courses->{$course}{'co-owners'} ne '') {
1242: foreach my $item (split(/,/,$courses->{$course}{'co-owners'})) {
1.22 raeburn 1243: push(@owners,$item);
1244: }
1245: }
1246: }
1.72 raeburn 1247: if ($instcode ne '') {
1248: $uniquecodes{$instcode} = 1;
1249: } else {
1250: $nocodes ++;
1251: }
1.22 raeburn 1252: foreach my $owner (@owners) {
1.54 raeburn 1253: my ($ownername,$ownerdom);
1.22 raeburn 1254: if ($owner =~ /:/) {
1255: ($ownername,$ownerdom) = split(/:/,$owner);
1256: } else {
1257: $ownername = $owner;
1258: if ($owner ne '') {
1259: $ownerdom = $cdom;
1260: }
1261: }
1262: if ($ownername ne '' && $ownerdom ne '') {
1263: my %namehash=&Apache::loncommon::getnames($ownername,$ownerdom);
1264: $ownernames{$ownername.':'.$ownerdom} = \%namehash;
1.1 raeburn 1265: }
1266: }
1267: $courseinfo{$course}{'cdom'} = $cdom;
1268: $courseinfo{$course}{'cnum'} = $cnum;
1269: $courseinfo{$course}{'code'} = $instcode;
1.22 raeburn 1270: my @lastnames;
1271: foreach my $owner (keys(%ownernames)) {
1272: if (ref($ownernames{$owner}) eq 'HASH') {
1273: push(@lastnames,$ownernames{$owner}{'lastname'});
1274: }
1275: }
1276: $courseinfo{$course}{'ownerlastnames'} = join(', ',sort(@lastnames));
1.1 raeburn 1277: $courseinfo{$course}{'title'} = $cleandesc;
1.22 raeburn 1278: $courseinfo{$course}{'owner'} = $singleowner;
1.27 raeburn 1279: $courseinfo{$course}{'selfenroll_types'} = $selfenroll_types;
1280: $courseinfo{$course}{'selfenroll_start'} = $selfenroll_start;
1281: $courseinfo{$course}{'selfenroll_end'} = $selfenroll_end;
1.35 raeburn 1282: $courseinfo{$course}{'categories'} = $categories;
1.7 raeburn 1283:
1284: my %coursehash = &Apache::lonnet::dump('environment',$cdom,$cnum);
1285: my @classids;
1286: my @crosslistings;
1.15 raeburn 1287: my ($seclist,$numsec) =
1288: &identify_sections($coursehash{'internal.sectionnums'});
1.7 raeburn 1289: $courseinfo{$course}{'seclist'} = $seclist;
1.15 raeburn 1290: my ($xlist_items,$numxlist) =
1291: &identify_sections($coursehash{'internal.crosslistings'});
1.72 raeburn 1292: if (ref($numbers) eq 'HASH') {
1293: $numbers->{'sections'} += $numsec;
1294: $numbers->{'xlists'} += $numxlist;
1295: }
1.7 raeburn 1296: my $showsyllabus = 1; # default is to include a syllabus link
1297: if (defined($coursehash{'showsyllabus'})) {
1298: $showsyllabus = $coursehash{'showsyllabus'};
1299: }
1300: $courseinfo{$course}{'showsyllabus'} = $showsyllabus;
1.73 raeburn 1301: if ($showcredits) {
1302: if ($coursehash{'internal.defaultcredits'}) {
1303: $courseinfo{$course}{'defaultcredits'} = $coursehash{'internal.defaultcredits'};
1304: } elsif ($instcode ne '') {
1305: $courseinfo{$course}{'defaultcredits'} = $defofficial;
1306: } else {
1307: $courseinfo{$course}{'defaultcredits'} = $defunofficial;
1308: }
1309: $defcreds = $courseinfo{$course}{'defaultcredits'};
1310: }
1.15 raeburn 1311: if (((defined($env{'form.coursenum'}) && ($cnum eq $env{'form.coursenum'}))) ||
1.22 raeburn 1312: ($knownuser && ($details == 1))) {
1.72 raeburn 1313: my $milestone;
1314: if ($wasactiveon eq 'accessend') {
1315: if ($coursehash{'default_enrollment_end_date'}) {
1316: $milestone = $coursehash{'default_enrollment_end_date'};
1317: } else {
1318: $milestone = time;
1319: }
1320: } elsif ($wasactiveon eq 'enrollend') {
1321: if ($coursehash{'internal.autoend'}) {
1322: $milestone = $coursehash{'internal.autoend'};
1323: } else {
1324: $milestone = time;
1325: }
1326: } else {
1327: $milestone = $wasactiveon;
1328: }
1329: $courseinfo{$course}{'counts'} =
1330: &count_students($cdom,$cnum,$numsec,$fields,$fieldtitles,$gettotals,
1.73 raeburn 1331: $numbers,$creditsum,$showcredits,$defcreds,$milestone);
1.72 raeburn 1332: if ($instcode ne '') {
1333: $courseinfo{$course}{'autoenrollment'} =
1334: &autoenroll_info(\%coursehash,$now,$seclist,$xlist_items,
1335: $instcode,\@owners,$cdom,$cnum);
1336: }
1.15 raeburn 1337: my $startaccess = '';
1338: my $endaccess = '';
1339: my $accessdates;
1340: if ( defined($coursehash{'default_enrollment_start_date'}) ) {
1341: $startaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_start_date'});
1342: }
1343: if ( defined($coursehash{'default_enrollment_end_date'}) ) {
1344: $endaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_end_date'});
1345: if ($coursehash{'default_enrollment_end_date'} == 0) {
1.34 raeburn 1346: $endaccess = &mt('No ending date');
1.15 raeburn 1347: }
1348: }
1349: if ($startaccess) {
1.42 bisitz 1350: $accessdates .= '<i>'.&mt('From:[_1]','</i> '.$startaccess).'<br />';
1.7 raeburn 1351: }
1.15 raeburn 1352: if ($endaccess) {
1.42 bisitz 1353: $accessdates .= '<i>'.&mt('To:[_1]','</i> '.$endaccess).'<br />';
1.15 raeburn 1354: }
1.34 raeburn 1355: if (($selfenroll_types ne '') &&
1356: ($selfenroll_end > 0 && $selfenroll_end > $now)) {
1357: my ($selfenroll_start_access,$selfenroll_end_access);
1358: if (($coursehash{'default_enrollment_start_date'} ne
1359: $coursehash{'internal.selfenroll_start_access'}) ||
1360: ($coursehash{'default_enrollment_end_date'} ne
1361: $coursehash{'internal.selfenroll_end_access'})) {
1362: if ( defined($coursehash{'internal.selfenroll_start_access'}) ) {
1363: $selfenroll_start_access = &Apache::lonlocal::locallocaltime($coursehash{'internal.selfenroll_start_access'});
1364: }
1365: if ( defined($coursehash{'default_enrollment_end_date'}) ) {
1366: $selfenroll_end_access = &Apache::lonlocal::locallocaltime($coursehash{'internal.selfenroll_end_access'});
1367: if ($coursehash{'internal.selfenroll_end_access'} == 0) {
1368: $selfenroll_end_access = &mt('No ending date');
1369: }
1370: }
1371: if ($selfenroll_start_access || $selfenroll_end_access) {
1372: $accessdates .= '<br/><br /><i>'.&mt('Self-enrollers:').'</i><br />';
1373: if ($selfenroll_start_access) {
1.42 bisitz 1374: $accessdates .= '<i>'.&mt('From:[_1]','</i> '.$selfenroll_start_access).'<br />';
1.34 raeburn 1375: }
1376: if ($selfenroll_end_access) {
1.42 bisitz 1377: $accessdates .= '<i>'.&mt('To:[_1]','</i> '.$selfenroll_end_access).'<br />';
1.34 raeburn 1378: }
1379: }
1380: }
1381: }
1.15 raeburn 1382: $courseinfo{$course}{'access'} = $accessdates;
1.1 raeburn 1383: }
1.7 raeburn 1384: if ($xlist_items eq '') {
1385: $xlist_items = &mt('No');
1.1 raeburn 1386: }
1.7 raeburn 1387: $courseinfo{$course}{'xlist'} = $xlist_items;
1.1 raeburn 1388: }
1.72 raeburn 1389: if (ref($numbers) eq 'HASH') {
1390: $numbers->{'courses'} = $nocodes + scalar(keys(%uniquecodes));
1391: }
1.7 raeburn 1392: return %courseinfo;
1.1 raeburn 1393: }
1394:
1.7 raeburn 1395: sub count_students {
1.73 raeburn 1396: my ($cdom,$cnum,$numsec,$fieldsref,$titlesref,$getcounts,$numbers,$creditsum,
1397: $showcredits,$defcreds,$wasactiveon) = @_;
1.72 raeburn 1398: my $countslist = '<span class="LC_nobreak">'.
1399: &mt('[quant,_1,section,sections,No sections]',$numsec).'</span>';
1400: my (@fields,%titles,$showexpired);
1401: if ((ref($fieldsref) eq 'ARRAY') && (ref($titlesref) eq 'HASH') &&
1402: (ref($numbers) eq 'HASH')) {
1403: @fields = @{$fieldsref};
1404: %titles = %{$titlesref};
1405: if (grep(/^Previous$/,@fields)) {
1406: $showexpired = 1;
1407: }
1408: } else {
1409: return;
1410: }
1.1 raeburn 1411: my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cnum);
1.73 raeburn 1412: my (%student_count,%credit_count);
1413: %student_count = (
1.72 raeburn 1414: Active => 0,
1415: Future => 0,
1416: Previous => 0,
1.73 raeburn 1417: );
1418: if ($showcredits) {
1419: %credit_count = (
1420: Active => 0,
1421: Future => 0,
1422: Previous => 0,
1423: );
1424: }
1.1 raeburn 1425: my %idx;
1426: $idx{'status'} = &Apache::loncoursedata::CL_STATUS();
1.72 raeburn 1427: $idx{'end'} = &Apache::loncoursedata::CL_END();
1.73 raeburn 1428: $idx{'credits'} = &Apache::loncoursedata::CL_CREDITS();
1.4 albertel 1429: while (my ($student,$data) = each(%$classlist)) {
1.72 raeburn 1430: my $status = $data->[$idx{'status'}];
1.73 raeburn 1431: my $credits = $data->[$idx{'credits'}];
1432: if ($credits eq '') {
1433: $credits = $defcreds;
1434: }
1.72 raeburn 1435: if ($status eq 'Expired') {
1436: if (($showexpired) &&
1437: ($data->[$idx{'end'}] >= $wasactiveon)) {
1438: $student_count{'Previous'} ++;
1.73 raeburn 1439: if ($showcredits) {
1440: $credit_count{'Previous'} += $credits;
1441: }
1.72 raeburn 1442: }
1443: } else {
1444: $student_count{$status} ++;
1.73 raeburn 1445: if ($showcredits) {
1446: $credit_count{$status} += $credits;
1447: }
1.72 raeburn 1448: }
1.1 raeburn 1449: }
1.72 raeburn 1450: if (@fields) {
1451: $countslist .= ':<br />';
1452: foreach my $status (@fields) {
1453: $countslist .= '<span class="LC_nobreak">'.$titles{$status}.': '.
1454: $student_count{$status}.'</span><br />';
1455: $numbers->{$status} += $student_count{$status};
1.73 raeburn 1456: if ($showcredits) {
1457: $creditsum->{$status} += $credit_count{$status};
1458: }
1.72 raeburn 1459: }
1.1 raeburn 1460: }
1.7 raeburn 1461: return $countslist;
1462: }
1463:
1464: sub courseinfo_row {
1.72 raeburn 1465: my ($info,$knownuser,$details,$countref,$now,$course,$trails,$allitems,$numbers) = @_;
1.7 raeburn 1466: my ($cdom,$cnum,$title,$ownerlast,$code,$owner,$seclist,$xlist_items,
1.35 raeburn 1467: $accessdates,$showsyllabus,$counts,$autoenrollment,$output,$categories);
1.7 raeburn 1468: if (ref($info) eq 'HASH') {
1469: $cdom = $info->{'cdom'};
1470: $cnum = $info->{'cnum'};
1471: $title = $info->{'title'};
1.22 raeburn 1472: $ownerlast = $info->{'ownerlastnames'};
1.7 raeburn 1473: $code = $info->{'code'};
1474: $owner = $info->{'owner'};
1475: $seclist = $info->{'seclist'};
1476: $xlist_items = $info->{'xlist'};
1477: $accessdates = $info->{'access'};
1478: $counts = $info->{'counts'};
1479: $autoenrollment = $info->{'autoenrollment'};
1480: $showsyllabus = $info->{'showsyllabus'};
1.35 raeburn 1481: $categories = $info->{'categories'};
1.7 raeburn 1482: } else {
1483: $output = '<td colspan="8">'.&mt('No information available for [_1].',
1484: $code).'</td>';
1485: return $output;
1.2 raeburn 1486: }
1.35 raeburn 1487: $output .= '<td>'.$$countref.'</td>';
1488: if ($env{'form.currcat_0'} eq 'instcode::0') {
1489: $output .= '<td>'.$code.'</td>';
1490: } else {
1491: my ($categorylist,@cats);
1492: if ($categories ne '') {
1493: @cats = split('&',$categories);
1494: }
1495: if ((ref($trails) eq 'ARRAY') && (ref($allitems) eq 'HASH')) {
1496: my @categories = map { $trails->[$allitems->{$_}]; } @cats;
1497: $categorylist = join('<br />',@categories);
1498: }
1499: if ($categorylist eq '') {
1500: $categorylist = ' ';
1501: }
1502: $output .= '<td>'.$categorylist.'</td>';
1503: }
1504: $output .= '<td>'.$seclist.'</td>'.
1.7 raeburn 1505: '<td>'.$xlist_items.'</td>'.
1506: '<td>'.$title.' <font size="-2">';
1.2 raeburn 1507: if ($showsyllabus) {
1.40 raeburn 1508: $output .= '<a href="javascript:ToSyllabus('."'$cdom','$cnum'".')">'.&mt('Syllabus').'</a>';
1.7 raeburn 1509: } else {
1510: $output .= ' ';
1.2 raeburn 1511: }
1512: $output .= '</font></td>'.
1.7 raeburn 1513: '<td>'.$ownerlast.'</td>';
1.15 raeburn 1514: if ($knownuser) {
1515: if ($details) {
1.72 raeburn 1516: $output .=
1517: '<td>'.$accessdates.'</td>'.
1518: '<td>'.$counts.'</td>';
1519: unless ($env{'form.currcat_0'} eq 'communities::0') {
1520: $output .= '<td>'.$autoenrollment.'</td>';
1.60 raeburn 1521: }
1.15 raeburn 1522: } else {
1523: $output .= "<td><a href=\"javascript:setCourseId('$cnum')\">".&mt('Show more details').'</a></td>';
1.8 raeburn 1524: }
1.7 raeburn 1525: }
1.82 raeburn 1526: my $selfenroll = &selfenroll_status($info,$course);
1527: if ($selfenroll) {
1528: $output .= '<td>'.$selfenroll.'</td>';
1529: } else {
1530: $output .= '<td> </td>';
1531: }
1532: $$countref ++;
1533: return $output;
1534: }
1535:
1536: sub selfenroll_status {
1537: my ($info,$course) = @_;
1538: my $now = time;
1539: my $output;
1540: if (ref($info) eq 'HASH') {
1541: if ($info->{'selfenroll_types'}) {
1542: my $showstart = &Apache::lonlocal::locallocaltime($info->{'selfenroll_start'});
1543: my $showend = &Apache::lonlocal::locallocaltime($info->{'selfenroll_end'});
1544: if (($info->{'selfenroll_end'} > 0) && ($info->{'selfenroll_end'} > $now)) {
1545: if (($info->{'selfenroll_start'} > 0) && ($info->{'selfenroll_start'} > $now)) {
1546: $output = &mt('Starts: [_1]','<span class="LC_cusr_emph">'.$showstart.'</span>').'<br />'.&mt('Ends: [_1]','<span class="LC_cusr_emph">'.$showend.'</span>');
1547: } else {
1548: $output = '<a href="javascript:ToSelfenroll('."'$course'".')">'.
1549: &mt('Enroll in course').'</a><br />';
1550: if ($info->{'selfenroll_end'} == 0) {
1551: $output .= &mt('Available permanently');
1552: } elsif ($info->{'selfenroll_end'} > $now) {
1553: $output .= &mt('Self-enrollment ends: [_1]','<span class="LC_cusr_emph">'.$showend.'</span>');
1554: }
1.66 raeburn 1555: }
1.27 raeburn 1556: }
1557: }
1558: }
1.1 raeburn 1559: return $output;
1560: }
1561:
1562: sub identify_sections {
1563: my ($seclist) = @_;
1564: my @secnums;
1565: if ($seclist =~ /,/) {
1.4 albertel 1566: my @sections = split(/,/,$seclist);
1.1 raeburn 1567: foreach my $sec (@sections) {
1568: $sec =~ s/:[^:]*$//;
1569: push(@secnums,$sec);
1570: }
1571: } else {
1572: if ($seclist =~ m/^([^:]+):/) {
1573: my $sec = $1;
1.4 albertel 1574: if (!grep(/^\Q$sec\E$/,@secnums)) {
1575: push(@secnums,$sec);
1.1 raeburn 1576: }
1577: }
1578: }
1579: @secnums = sort {$a <=> $b} @secnums;
1.39 raeburn 1580: $seclist = join(', ',@secnums);
1.15 raeburn 1581: my $numsec = @secnums;
1582: return ($seclist,$numsec);
1.1 raeburn 1583: }
1584:
1.2 raeburn 1585: sub get_valid_classes {
1.22 raeburn 1586: my ($seclist,$xlist_items,$crscode,$owners,$cdom,$cnum) = @_;
1.2 raeburn 1587: my $response;
1588: my %validations;
1589: @{$validations{'sections'}} = ();
1590: @{$validations{'xlists'}} = ();
1591: my $totalitems = 0;
1592: if ($seclist) {
1.13 raeburn 1593: foreach my $sec (split(/, /,$seclist)) {
1.2 raeburn 1594: my $class = $crscode.$sec;
1.22 raeburn 1595: if (&Apache::lonnet::auto_validate_class_sec($cdom,$cnum,$owners,
1.3 albertel 1596: $class) eq 'ok') {
1.2 raeburn 1597: if (!grep(/^\Q$sec$\E/,@{$validations{'sections'}})) {
1.4 albertel 1598: push(@{$validations{'sections'}},$sec);
1.2 raeburn 1599: $totalitems ++;
1600: }
1601: }
1602: }
1603: }
1604: if ($xlist_items) {
1.13 raeburn 1605: foreach my $item (split(/, /,$xlist_items)) {
1.22 raeburn 1606: if (&Apache::lonnet::auto_validate_class_sec($cdom,$cnum,$owners,
1.3 albertel 1607: $item) eq 'ok') {
1.2 raeburn 1608: if (!grep(/^\Q$item$\E/,@{$validations{'xlists'}})) {
1.4 albertel 1609: push(@{$validations{'xlists'}},$item);
1.2 raeburn 1610: $totalitems ++;
1611: }
1612: }
1613: }
1614: }
1615: if ($totalitems > 0) {
1616: if (@{$validations{'sections'}}) {
1.42 bisitz 1617: $response = &mt('Sections:').' '.
1.14 raeburn 1618: join(', ',@{$validations{'sections'}}).'<br />';
1.2 raeburn 1619: }
1620: if (@{$validations{'xlists'}}) {
1.42 bisitz 1621: $response .= &mt('Courses:').' '.
1.14 raeburn 1622: join(', ',@{$validations{'xlists'}});
1.2 raeburn 1623: }
1624: }
1625: return $response;
1626: }
1627:
1.7 raeburn 1628: sub autoenroll_info {
1.22 raeburn 1629: my ($coursehash,$now,$seclist,$xlist_items,$code,$owners,$cdom,$cnum) = @_;
1.7 raeburn 1630: my $autoenrolldates = &mt('Not enabled');
1631: if (defined($coursehash->{'internal.autoadds'}) && $coursehash->{'internal.autoadds'} == 1) {
1632: my ($autostart,$autoend);
1633: if ( defined($coursehash->{'internal.autostart'}) ) {
1634: $autostart = &Apache::lonlocal::locallocaltime($coursehash->{'internal.autostart'});
1635: }
1636: if ( defined($coursehash->{'internal.autoend'}) ) {
1637: $autoend = &Apache::lonlocal::locallocaltime($coursehash->{'internal.autoend'});
1638: }
1639: if ($coursehash->{'internal.autostart'} > $now) {
1640: if ($coursehash->{'internal.autoend'} && $coursehash->{'internal.autoend'} < $now) {
1641: $autoenrolldates = &mt('Not enabled');
1642: } else {
1643: my $valid_classes =
1644: &get_valid_classes($seclist,$xlist_items,$code,
1.22 raeburn 1645: $owners,$cdom,$cnum);
1.7 raeburn 1646: if ($valid_classes ne '') {
1.42 bisitz 1647: $autoenrolldates = &mt('Not enabled').'<br />'
1648: .&mt('Starts: [_1]',$autostart)
1649: .'<br />'.$valid_classes;
1650: }
1.7 raeburn 1651: }
1652: } else {
1653: if ($coursehash->{'internal.autoend'} && $coursehash->{'internal.autoend'} < $now) {
1.42 bisitz 1654: $autoenrolldates = &mt('Not enabled').'<br />'
1655: .&mt('Ended: [_1]',$autoend);
1.7 raeburn 1656: } else {
1657: my $valid_classes = &get_valid_classes($seclist,$xlist_items,
1.22 raeburn 1658: $code,$owners,$cdom,$cnum);
1.7 raeburn 1659: if ($valid_classes ne '') {
1.42 bisitz 1660: $autoenrolldates = &mt('Currently enabled').'<br />'.
1.7 raeburn 1661: $valid_classes;
1662: }
1663: }
1664: }
1665: }
1666: return $autoenrolldates;
1667: }
1668:
1.8 raeburn 1669: sub user_is_known {
1670: my $known = 0;
1671: if ($env{'user.name'} ne '' && $env{'user.name'} ne 'public'
1672: && $env{'user.domain'} ne '' && $env{'user.domain'} ne 'public') {
1673: $known = 1;
1674: }
1675: return $known;
1676: }
1677:
1.1 raeburn 1678: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>