Annotation of loncom/interface/coursecatalog.pm, revision 1.108
1.17 albertel 1: # The LearningOnline Network with CAPA
2: # Handler for displaying the course catalog interface
3: #
1.108 ! raeburn 4: # $Id: coursecatalog.pm,v 1.107 2025/02/24 13:40:33 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;
1.108 ! raeburn 40: use HTML::Entities();
1.1 raeburn 41: use LONCAPA;
1.86 raeburn 42: use LONCAPA::lonauthcgi;
1.1 raeburn 43:
44: sub handler {
45: my ($r) = @_;
46: &Apache::loncommon::content_type($r,'text/html');
47: $r->send_http_header;
48: if ($r->header_only) {
49: return OK;
50: }
1.21 albertel 51: my $handle = &Apache::lonnet::check_for_valid_session($r);
1.8 raeburn 52: my $lonidsdir=$r->dir_config('lonIDsDir');
1.21 albertel 53: if ($handle ne '') {
1.8 raeburn 54: &Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle);
55: }
1.1 raeburn 56: &Apache::lonacc::get_posted_cgi($r);
57: &Apache::lonlocal::get_language_handle($r);
1.38 raeburn 58: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
59: ['sortby','showdom']);
1.28 raeburn 60:
1.93 raeburn 61: my $serverdefdom = &Apache::lonnet::default_login_domain();
62: my $codedom = $serverdefdom;
1.103 raeburn 63: my $hostname = $r->hostname();
1.19 raeburn 64:
65: if (($env{'user.domain'} ne '') && ($env{'user.domain'} ne 'public')) {
66: $codedom = $env{'user.domain'};
67: if ($env{'request.role.domain'} ne '') {
68: $codedom = $env{'request.role.domain'};
69: }
70: }
1.7 raeburn 71: my $formname = 'coursecatalog';
1.28 raeburn 72: if ($env{'form.showdom'} ne '') {
1.75 raeburn 73: $env{'form.showdom'} = &LONCAPA::clean_domain($env{'form.showdom'});
1.28 raeburn 74: if (&Apache::lonnet::domain($env{'form.showdom'}) ne '') {
75: $codedom = $env{'form.showdom'};
1.75 raeburn 76: } else {
77: $env{'form.showdom'} = '';
1.28 raeburn 78: }
79: }
1.93 raeburn 80: my $domdesc = &Apache::lonnet::domain($serverdefdom,'description');
1.7 raeburn 81: &Apache::lonhtmlcommon::clear_breadcrumbs();
1.94 raeburn 82:
83: unless (($serverdefdom eq $codedom) ||
84: (&Apache::lonnet::will_trust('catalog',$serverdefdom,$codedom))) {
1.93 raeburn 85: my $serverdomdesc = &Apache::lonnet::domain($serverdefdom,'description');
86: $r->print(&Apache::loncommon::start_page('Course/Community Catalog'));
87: &Apache::lonhtmlcommon::add_breadcrumb
88: ({href=>"/adm/coursecatalog",
89: text=>"Course/Community Catalog"});
90: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog'));
1.108 ! raeburn 91: $r->print('<div role="main">'.&mt('Access to catalog LON-CAPA courses/communities unavailable for: "[_1]" on servers run by: "[_2]".',
1.93 raeburn 92: $domdesc,$serverdomdesc).'</div>');
93: $r->print(&Apache::loncommon::end_page());
94: return OK;
95: }
1.101 raeburn 96: my $crscats = &Apache::lonnet::get_dom_cats($codedom);
97: my %domdefaults = &Apache::lonnet::get_domain_defaults($codedom);
1.82 raeburn 98: my $knownuser = &user_is_known();
1.90 raeburn 99: my $canviewall = &canview_all($knownuser,$codedom);
1.86 raeburn 100:
1.82 raeburn 101: my ($cathash,$cattype);
1.101 raeburn 102: if (ref($crscats) eq 'HASH') {
103: %{$cathash} = %{$crscats};
1.35 raeburn 104: } else {
105: $cathash = {};
1.101 raeburn 106: }
107: if ($knownuser || $canviewall) {
108: $cattype = $domdefaults{'catauth'};
109: } else {
110: $cattype = $domdefaults{'catunauth'};
111: }
112: if ($cattype eq '') {
1.83 raeburn 113: $cattype = 'std';
1.82 raeburn 114: }
115: if ($cattype eq 'none') {
116: $r->print(&Apache::loncommon::start_page('Course/Community Catalog'));
117: &Apache::lonhtmlcommon::add_breadcrumb
118: ({href=>"/adm/coursecatalog",
119: text=>"Course/Community Catalog"});
120: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog'));
1.86 raeburn 121: if ($knownuser || $canviewall) {
1.108 ! raeburn 122: $r->print('<div role="main">'.&mt('No catalog of LON-CAPA courses/communities is provided for: [_1]',$domdesc).'</div>');
1.82 raeburn 123: } else {
1.101 raeburn 124: if ($domdefaults{'catauth'} eq 'none') {
1.108 ! raeburn 125: $r->print('<div role="main">'.&mt('No catalog of LON-CAPA courses/communities is provided for: [_1]',$domdesc).'</div>');
1.82 raeburn 126: } else {
1.108 ! raeburn 127: $r->print('<div role="main">'.&mt('The catalog of LON-CAPA courses/communities provided for: "[_1]" is only available to users who are logged in.',$domdesc).'</div>');
1.82 raeburn 128: }
129: }
130: $r->print(&Apache::loncommon::end_page());
131: return OK;
132: }
133:
1.108 ! raeburn 134: for (my $i=0; $i<=$env{'form.catalog_maxdepth'}; $i++) {
! 135: if ($env{'form.currcat_'.$i} eq '-1') {
! 136: $env{'form.currcat_'.$i} = '';
! 137: }
! 138: if (exists($env{'form.initialcurrcat_'.$i})) {
! 139: if ($env{'form.currcat_'.$i} ne $env{'form.initialcurrcat_'.$i}) {
! 140: $env{'form.catalog_maxdepth'} = $i;
! 141: last;
! 142: }
! 143: }
! 144: }
! 145:
1.101 raeburn 146: my $cnum;
1.82 raeburn 147: if ($cattype eq 'codesrch') {
148: my ($uniquecode,$codemsg,$brtext);
149: if ($env{'form.uniquecode'}) {
150: $uniquecode = $env{'form.uniquecode'};
151: $uniquecode =~ s/^\s+|\s+$//g;
152: }
153: my $js = '<script type="text/javascript">'."\n".
154: '// <![CDATA['."\n".
1.103 raeburn 155: &courselink_javascript($hostname)."\n".
1.82 raeburn 156: '// ]]>'."\n".
157: '</script>'."\n";
158: $r->print(&Apache::loncommon::start_page('Search for a Course/Community',$js));
159: if ($uniquecode =~ /^\w{6}$/) {
160: &Apache::lonhtmlcommon::add_breadcrumb
161: ({href=>"/adm/coursecatalog",
162: text=>"Course/Community Catalog"});
163: $brtext = 'Search Result';
164: } else {
165: $brtext = 'Course/Community Catalog';
166: }
167: &Apache::lonhtmlcommon::add_breadcrumb
168: ({href=>"/adm/coursecatalog",
169: text=>"$brtext"});
170: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog'));
171: $r->print(&coursesearch($codedom,$domdesc,$uniquecode));
172: if ($uniquecode =~ /^\w{6}$/) {
173: $r->print('<hr />');
174: my $confname = $codedom.'-domainconfig';
175: my %codes = &Apache::lonnet::get('uniquecodes',[$uniquecode],$codedom,$confname);
176: if ($codes{$uniquecode}) {
177: $cnum = $codes{$uniquecode};
178: my %courses = &Apache::lonnet::courseiddump($codedom,'.',1,'.','.',
179: $cnum,undef,undef,'.',1);
180: if (keys(%courses)) {
1.86 raeburn 181: $env{'form.coursenum'} = $cnum;
182: my %courseinfo = &build_courseinfo_hash(\%courses,$knownuser,$codedom,$canviewall);
1.82 raeburn 183: undef($env{'form.coursenum'});
184: if (ref($courseinfo{$codedom.'_'.$cnum}) eq 'HASH') {
185: $r->print(&Apache::lonhtmlcommon::start_pick_box());
186: my @cols = ('title','ownerlastnames','seclist','access');
187: my %lt = &Apache::lonlocal::texthash(
188: title => 'Title',
189: ownerlastnames => 'Owner & Co-owner(s)',
190: seclist => 'Sections',
191: access => 'Default Access Dates for Students',
192: );
193: my @shown;
194: foreach my $item (@cols) {
195: if ($courseinfo{$codedom.'_'.$cnum}{$item}) {
196: push(@shown,$item);
197: }
198: }
199: my $num = 0;
200: foreach my $item (@shown) {
201: $num ++;
202: $r->print(&Apache::lonhtmlcommon::row_title($lt{$item}).
203: $courseinfo{$codedom.'_'.$cnum}{$item});
204: if ($item eq 'title') {
205: if ($courseinfo{$codedom.'_'.$cnum}{'showsyllabus'}) {
1.91 raeburn 206: my $usehttp = 0;
207: if (($ENV{'SERVER_PORT'} == 443) && ($courseinfo{$codedom.'_'.$cnum}{'extsyllplain'})) {
1.103 raeburn 208: unless ((&Apache::lonnet::uses_sts()) ||
209: (&Apache::lonnet::waf_allssl($hostname))) {
1.98 raeburn 210: $usehttp = 1;
211: }
1.91 raeburn 212: }
1.82 raeburn 213: $r->print(' <font size="-2">'.
1.91 raeburn 214: '<a href="javascript:ToSyllabus('."'$codedom','$cnum','$usehttp'".')">'.
1.82 raeburn 215: &mt('Syllabus').'</a></font>');
216: }
217: }
218: my $arg = ( $num == scalar(@shown) ? 1 : '' );
219: $r->print(&Apache::lonhtmlcommon::row_closure($arg));
220: }
221: $r->print(&Apache::lonhtmlcommon::end_pick_box());
222: my $selfenroll = &selfenroll_status($courseinfo{$codedom.'_'.$cnum},$codedom.'_'.$cnum);
223: if ($selfenroll) {
224: $r->print('<br />'.$selfenroll);
225: }
226: $r->print('<form name="linklaunch" method="post" action="">'."\n".
227: '<input type="hidden" name="backto" value="coursecatalog" />'."\n".
228: '<input type="hidden" name="courseid" value="" />'."\n".
229: '</form>'."\n");
230:
231: } else {
232: $codemsg = &mt('Code matched, but course ID to which this mapped is invalid.');
233: }
234: } else {
235: $codemsg = &mt('Code matched, but course ID to which this mapped is invalid.');
236: }
237: } else {
238: $codemsg = &mt('No match');
239: }
240: }
241: $r->print('<br />'.&Apache::loncommon::end_page());
242: return OK;
243: } else {
1.96 raeburn 244: if ($env{'form.coursenum'} ne '') {
245: if ($env{'form.coursenum'} =~ /^$LONCAPA::match_courseid$/) {
246: $cnum = $env{'form.coursenum'};
247: } else {
248: delete($env{'form.coursenum'});
249: }
1.82 raeburn 250: }
1.35 raeburn 251: }
1.82 raeburn 252:
1.96 raeburn 253: my (@cats,@trails,%allitems,%idx,@jsarray,%subcathash,$subcats,%maxd,
254: $toplevelstr,$maxdepthstr);
1.36 raeburn 255: if ($env{'form.withsubcats'}) {
256: $subcats = \%subcathash;
257: }
1.35 raeburn 258: &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,\%allitems,
1.96 raeburn 259: \%idx,\@jsarray,$subcats,\%maxd);
260: if (ref($cats[0]) eq 'ARRAY') {
261: foreach my $item (@{$cats[0]}) {
262: $toplevelstr .= "'".&js_escape($item)."::0',";
263: $maxdepthstr .= "'$maxd{$item}',";
264: }
265: $toplevelstr =~ s/,$//;
266: $maxdepthstr =~ s/,$//;
267: }
1.101 raeburn 268: &validate_input($codedom,\@cats,\%maxd,$cathash);
1.63 raeburn 269: my ($numtitles,@codetitles);
1.82 raeburn 270: if (($env{'form.coursenum'} ne '') && ($knownuser)) {
1.103 raeburn 271: &course_details($r,$codedom,$formname,$domdesc,$hostname,\@trails,
272: \%allitems,\@codetitles);
1.7 raeburn 273: } else {
1.46 raeburn 274: my ($catlinks,$has_subcats,$selitem) = &category_breadcrumbs($codedom,@cats);
1.72 raeburn 275: my $wasacctext = &get_wasactive_text();
1.108 ! raeburn 276: my %js_lt = &Apache::lonlocal::texthash(
! 277: 'noch' => 'No changes made in drop-down lists',
! 278: 'chsu' => 'Choose a subcategory to display',
! 279: 'chca' => 'Choose a category to display',
! 280: );
! 281: &js_escape(\%js_lt);
1.28 raeburn 282: my $catjs = <<"ENDSCRIPT";
283:
1.33 raeburn 284: function changeSort(caller) {
285: document.$formname.sortby.value = caller;
286: document.$formname.submit();
287: }
1.40 raeburn 288:
1.33 raeburn 289: function setCourseId(caller) {
290: document.$formname.coursenum.value = caller;
291: document.$formname.submit();
1.37 raeburn 292: }
293:
294: ENDSCRIPT
1.103 raeburn 295: $catjs .= &courselink_javascript($hostname);
1.86 raeburn 296: if (&user_is_dc($codedom) || $canviewall) {
1.72 raeburn 297: $catjs .= <<ENDTOGGJS
298:
299: function toggleStatuses() {
300: if (document.$formname.showdetails.checked) {
301: document.getElementById('statuschoice').style.display='block';
302: document.getElementById('statuscell').style.borderLeft='1px solid';
303: } else {
304: document.getElementById('statuschoice').style.display='none';
305: document.getElementById('statuscell').style.borderLeft='0px';
306: }
307: return;
308: }
309:
310: function toggleWasActive() {
311: if (document.getElementById('counts_Previous')) {
312: if (document.getElementById('counts_Previous').checked) {
313: document.getElementById('choosewasactive').style.display='block';
314: document.getElementById('choosewasacctext').innerHTML = '$wasacctext';
315: } else {
316: document.getElementById('choosewasactive').style.display='none';
317: document.getElementById('choosewasacctext').innerHTML = '';
318: }
319: }
320: return;
321: }
322:
323: ENDTOGGJS
324: }
1.28 raeburn 325: if ($env{'form.currcat_0'} eq 'instcode::0') {
326: $numtitles = &instcode_course_selector($r,$codedom,$formname,$domdesc,
1.86 raeburn 327: $catlinks,$catjs,\@codetitles,$cattype,$canviewall);
1.28 raeburn 328: if ($env{'form.state'} eq 'listing') {
1.63 raeburn 329: $r->print(&print_course_listing($codedom,$numtitles,undef,undef,undef,
1.104 raeburn 330: \@codetitles,$canviewall,$hostname));
1.28 raeburn 331: }
332: } else {
333: my (%add_entries);
1.50 raeburn 334: my ($currdepth,$deeper) = &get_depth_values();
1.108 ! raeburn 335: my $alert = $js_lt{'chsu'};
! 336: if (!$deeper) {
! 337: $alert = $js_lt{'chca'};
! 338: }
! 339: $catjs .= <<"ENDJS";
! 340: function check_selected() {
! 341: var currdepth = parseInt('$currdepth');
! 342: var countchanged = 0;
! 343: for (var i=0; i<=currdepth; i++) {
! 344: var selidx = document.coursecats.elements['currcat_'+i].selectedIndex;
! 345: var selvalue = document.coursecats.elements['currcat_'+i].options[selidx].value;
! 346: if (i<currdepth) {
! 347: var initialvalue = document.coursecats.elements['initialcurrcat_'+i].value;
! 348: if (selvalue != initialvalue) {
! 349: countchanged ++;
! 350: }
! 351: } else {
! 352: if (countchanged == 0) {
! 353: if (selvalue == "") {
! 354: alert('$alert');
! 355: return false;
! 356: } else {
! 357: countchanged ++;
1.50 raeburn 358: }
1.108 ! raeburn 359: }
! 360: }
! 361: }
! 362: if (countchanged == 0) {
! 363: alert("$js_lt{'noch'}");
1.46 raeburn 364: return false;
365: }
366: }
367: ENDJS
1.106 raeburn 368: my $js = '<script type="text/javascript">'."\n".
369: '// <![CDATA['."\n".
370: "$catjs\n".
371: '// ]]>'."\n".
372: '</script>';
373: &cat_header($r,$codedom,$js,\%add_entries,$catlinks,undef,$cattype);
1.28 raeburn 374: if ($env{'form.currcat_0'} ne '') {
1.33 raeburn 375: $r->print('<form name="'.$formname.
376: '" method="post" action="/adm/coursecatalog">'.
1.86 raeburn 377: &additional_filters($codedom,$has_subcats,$canviewall)."\n");
1.33 raeburn 378: $r->print('<input type="hidden" name="catalog_maxdepth" value="'.
379: $deeper.'" />'."\n");
380: for (my $i=0; $i<$deeper; $i++) {
381: $r->print('<input type="hidden" name="currcat_'.$i.'" value="'.$env{'form.currcat_'.$i}.'" />'."\n");
382: }
1.57 raeburn 383: my $display_button;
384: if ($env{'form.currcat_0'} eq 'communities::0') {
385: $display_button = &mt('Display communities');
1.89 raeburn 386: } elsif ($env{'form.currcat_0'} eq 'placement::0') {
387: $display_button = &mt('Display placement tests');
1.57 raeburn 388: } else {
389: $display_button = &mt('Display courses');
390: }
1.33 raeburn 391: $r->print('<input type="hidden" name="coursenum" value="" />'."\n".
392: '<input type="hidden" name="sortby" value="" />'."\n".
393: '<input type="hidden" name="state" value="listing" />'."\n".
394: '<input type="hidden" name="showdom" value="'.
395: $env{'form.showdom'}.'" />'.
396: '<input type="submit" name="catalogfilter" value="'.
1.57 raeburn 397: $display_button.'" /></form><br /><br />');
1.33 raeburn 398: }
399: if ($env{'form.state'} eq 'listing') {
1.86 raeburn 400: $r->print(&print_course_listing($codedom,undef,\@trails,\%allitems,$subcats,\@codetitles,
1.104 raeburn 401: $canviewall,$hostname));
1.28 raeburn 402: }
1.18 raeburn 403: }
1.108 ! raeburn 404: $r->print('</div>');
1.7 raeburn 405: }
1.108 ! raeburn 406: $r->print(&Apache::loncommon::end_page());
1.7 raeburn 407: return OK;
408: }
409:
1.96 raeburn 410: sub validate_input {
1.101 raeburn 411: my ($codedom,$cats,$maxd,$crscatsref) = @_;
1.96 raeburn 412: my $currcat = '';
413: my $depth = 0;
414: if ($env{'form.catalog_maxdepth'} ne '') {
415: $env{'form.catalog_maxdepth'} =~ s{\D}{}g;
416: }
417: if ((ref($cats) eq 'ARRAY') && (ref($maxd) eq 'HASH')) {
418: if (ref($cats->[0]) eq 'ARRAY') {
419: if (@{$cats->[0]} == 1) {
420: if ($cats->[0][0] eq 'instcode') {
421: $currcat = 'instcode::0';
422: } elsif ($cats->[0][0] eq 'communities') {
423: $currcat = 'communities::0';
424: } elsif ($cats->[0][0] eq 'placement') {
425: $currcat = 'placement::0';
426: } else {
427: my $name = $cats->[0][0];
428: $currcat = &escape($name).'::0';
429: }
430: if (exists($maxd->{$cats->[0][0]})) {
431: if ($env{'form.catalog_maxdepth'} <= $maxd->{$cats->[0][0]}) {
432: $depth = $env{'form.catalog_maxdepth'};
433: } else {
434: $depth = $maxd->{$cats->[0][0]};
435: }
436: }
437: } elsif ((@{$cats->[0]} > 1) && ($env{'form.currcat_0'} ne '')) {
438: my ($escname) = ($env{'form.currcat_0'} =~ /^([^:]+)\:\:0$/);
439: if ($escname =~ /^instcode|communities|placement$/) {
440: $currcat = $env{'form.currcat_0'};
441: if (exists($maxd->{$escname})) {
442: if ($env{'form.catalog_maxdepth'} <= $maxd->{$escname}) {
443: $depth = $env{'form.catalog_maxdepth'};
444: } else {
445: $depth = $maxd->{$escname};
446: }
447: } else {
448: $depth = 1;
449: }
450: } elsif ($escname ne '') {
451: my $name = &unescape($escname);
452: if (grep(/^\Q$name\E$/,@{$cats->[0]})) {
453: $currcat = $env{'form.currcat_0'};
454: if (exists($maxd->{$name})) {
455: if ($env{'form.catalog_maxdepth'} <= $maxd->{$name}) {
456: $depth = $env{'form.catalog_maxdepth'};
457: } else {
458: $depth = $maxd->{$name};
459: }
460: }
461: }
462: }
463: }
464: }
465: }
466: $env{'form.currcat_0'} = $currcat;
467: $env{'form.catalog_maxdepth'} = $depth;
1.99 raeburn 468:
469: my %possibles = (
470: backto => 1,
471: catalogfilter => 1,
472: catalog_maxdepth => 1,
473: courseid => 1,
474: coursenum => 1,
475: currcat_0 => 1,
476: numtitles => 1,
477: Year => 1,
478: Semester => 1,
479: Department => 1,
480: Number => 1,
481: showdom => 1,
482: sortby => 1,
483: showcounts => 1,
484: showdetails => 1,
485: showhidden => 1,
486: showselfenroll => 1,
487: state => 1,
488: uniquecode => 1,
489: wasactive => 1,
490: wasactiveon_day => 1,
491: wasactiveon_month => 1,
492: wasactiveon_year => 1,
493: withsubcats => 1,
494: );
495: my %currcats;
496: if ($env{'form.catalog_maxdepth'} > 0) {
497: for (my $i=1; $i<=$env{'form.catalog_maxdepth'}; $i++) {
498: $currcats{'currcat_'.$i} = 1;
499: $possibles{'currcat_'.$i} = 1;
500: }
501: }
502:
503: foreach my $key (sort(keys(%env))) {
1.108 ! raeburn 504: if ($key =~ /^form\.currcat_(.+)$/) {
! 505: unless ($possibles{'currcat_'.$1}) {
1.99 raeburn 506: delete($env{$key});
507: }
508: }
509: }
510: if (exists($env{'form.backto'})) {
511: unless ($env{'form.backto'} eq 'coursecatalog') {
512: delete($env{'form.backto'});
513: }
514: }
515: if (exists($env{'form.catalogfilter'})) {
516: unless (($env{'form.catalogfilter'} eq &mt('Display courses')) ||
517: ($env{'form.catalogfilter'} eq &mt('Display communities')) ||
518: ($env{'form.catalogfilter'} eq &mt('Display placement tests'))) {
519: delete($env{'form.catalogfilter'});
520: }
521: }
522: if (exists($env{'form.courseid'})) {
523: if ($env{'form.courseid'} ne '') {
524: unless ($env{'form.courseid'} =~ /^\Q$codedom\E_$LONCAPA::match_courseid$/) {
525: $env{'form.courseid'} = '';
526: }
527: }
528: }
529: if (exists($env{'form.coursenum'})) {
530: unless ($env{'form.coursenum'} =~ /^$LONCAPA::match_courseid$/) {
531: $env{'form.coursenum'} = '';
532: }
533: }
534: if (exists($env{'form.currcat_0'})) {
535: unless ($env{'form.currcat_0'} =~ /^(instcode|communities|placement)\Q::0\E$/) {
536: if ($env{'form.currcat_0'} =~ /^.+\Q::0\E$/) {
1.101 raeburn 537: if (ref($crscatsref) eq 'HASH') {
538: unless (exists($crscatsref->{$env{'form.currcat_0'}})) {
1.99 raeburn 539: delete($env{'form.currcat_0'});
540: }
541: } else {
542: delete($env{'form.currcat_0'});
543: }
544: } else {
545: delete($env{'form.currcat_0'});
546: }
547: }
548: }
549: if (exists($env{'form.numtitles'})) {
550: unless ($env{'form.numtitles'} =~ /^\d+$/) {
551: delete($env{'form.numtitles'});
552: }
553: }
554: my ($gotcodes,%possvals);
555: foreach my $item ('Year','Semester','Department','Number') {
556: if (exists($env{'form.'.$item})) {
557: unless ($env{'form.'.$item} eq '0') {
558: unless ($gotcodes) {
559: $gotcodes = &get_instcode_allowable($codedom,\%possvals);
560: }
561: if (ref($possvals{$item}) eq 'HASH') {
562: unless (exists($possvals{$item}{$env{'form.'.$item}})) {
563: delete($env{'form.'.$item});
564: }
565: } else {
566: delete($env{'form.'.$item});
567: }
568: }
569: }
570: }
571: if (exists($env{'form.showdom'})) {
572: unless ($env{'form.showdom'} =~ /^$LONCAPA::match_domain$/) {
573: delete($env{'form.showdom'});
574: }
575: }
576: if (exists($env{'form.sortby'})) {
577: unless ($env{'form.sortby'} =~ /^(title|code|owner|cats)$/) {
578: delete($env{'form.sortby'});
579: }
580: }
581: if (exists($env{'form.showcounts'})) {
582: if (ref($env{'form.showcounts'}) eq 'ARRAY') {
583: foreach my $item (@{$env{'form.showcounts'}}) {
584: unless ($item =~ /^(Active|Future|Previous)$/) {
585: delete($env{'form.showcounts'});
586: last;
587: }
588: }
589: } else {
590: unless ($env{'form.showcounts'} =~ /^(Active|Future|Previous)$/) {
591: delete($env{'form.showcounts'});
592: }
593: }
594: }
595: foreach my $item ('showhidden','showdetails','showselfenroll','withsubcats') {
596: if (exists($env{'form.'.$item})) {
597: unless ($env{'form.'.$item} eq '1') {
598: delete($env{'form.'.$item});
599: }
600: }
601: }
602: if (exists($env{'form.state'})) {
603: unless ($env{'form.state'} eq 'listing') {
604: delete($env{'form.state'});
605: }
606: }
607: if (exists($env{'form.uniquecode'})) {
608: unless ($env{'form.uniquecode'} =~ /^\w{6}$/) {
1.100 raeburn 609: delete($env{'form.uniquecode'});
1.99 raeburn 610: }
611: }
612: if (exists($env{'form.wasactive'})) {
613: unless (($env{'form.wasactive'} eq 'accessend') || ($env{'form.wasactive'} eq 'enrollend')) {
614: delete($env{'form.wasactive'});
615: }
616: }
617: if (exists($env{'form.wasactiveon_day'})) {
618: my $tmpday = $env{'form.wasactiveon_day'};
619: unless (($tmpday =~ /^\d+$/) && ($tmpday > 0) && ($tmpday < 32)) {
620: delete($env{'form.wasactiveon_day'});
621: }
622: }
623: if (exists($env{'form.wasactiveon_month'})) {
624: my $tmpmonth = $env{'form.wasactiveon_month'};
625: unless (($tmpmonth =~ /^\d+$/) && ($tmpmonth > 0) && ($tmpmonth < 13)) {
626: delete($env{'form.wasactiveon_month'});
627: }
628: }
629: if (exists($env{'form.wasactiveon_year'})) {
630: my $tmpyear = $env{'form.wasactiveon_year'};
631: unless (($tmpyear =~ /^\d+$/) && ($tmpyear >= 1970)) {
632: delete($env{'form.wasactiveon_year'});
633: }
634: }
635: if (keys(%currcats)) {
636: foreach my $key (keys(%currcats)) {
637: if ($env{'form.'.$key} eq '') {
638: delete($env{'form.'.$key});
1.101 raeburn 639: } elsif (ref($crscatsref) eq 'HASH') {
640: unless (exists($crscatsref->{$env{'form.'.$key}})) {
641: delete($env{'form.'.$key});
1.99 raeburn 642: }
643: } else {
644: delete($env{'form.'.$key});
645: }
646: }
647: }
1.96 raeburn 648: return;
649: }
650:
1.99 raeburn 651: sub get_instcode_allowable {
652: my ($codedom,$possvalref) = @_;
653: return 1 unless (ref($possvalref) eq 'HASH');
1.102 raeburn 654: my $instcats = &Apache::lonnet::get_dom_instcats($codedom);
655: if (ref($instcats) eq 'HASH') {
656: if ((ref($instcats->{'codetitles'}) eq 'ARRAY') && (ref($instcats->{'codes'}) eq 'HASH')) {
657: my %codes = %{$instcats->{'codes'}};
658: my @codetitles = @{$instcats->{'codetitles'}};
1.99 raeburn 659: my @standardnames = &Apache::loncommon::get_standard_codeitems();
660: my %local_to_standard;
661: for (my $i=0; $i<@codetitles; $i++) {
662: $local_to_standard{$codetitles[$i]} = $standardnames[$i];
663: $possvalref->{$standardnames[$i]} = {};
664: }
665: foreach my $cid (sort(keys(%codes))) {
666: if (ref($codes{$cid}) eq 'HASH') {
667: foreach my $item (keys(%{$codes{$cid}})) {
668: $possvalref->{$local_to_standard{$item}}{$codes{$cid}{$item}} = 1;
669: }
670: }
671: }
672: }
673: }
674: return 1;
675: }
676:
1.7 raeburn 677: sub course_details {
1.103 raeburn 678: my ($r,$codedom,$formname,$domdesc,$hostname,$trails,$allitems,$codetitles) = @_;
1.7 raeburn 679: my $output;
680: my %add_entries = (topmargin => "0",
681: marginheight => "0",);
1.40 raeburn 682: my $js = '<script type="text/javascript">'."\n".
1.103 raeburn 683: &courselink_javascript($hostname).'</script>'."\n";
1.7 raeburn 684: my $start_page =
1.56 bisitz 685: &Apache::loncommon::start_page('Course/Community Catalog',$js,
1.72 raeburn 686: {'add_entries' => \%add_entries, });
1.7 raeburn 687: $r->print($start_page);
1.19 raeburn 688: if ($env{'form.numtitles'} > 0) {
689: &Apache::lonhtmlcommon::add_breadcrumb
690: ({href=>"/adm/coursecatalog",
1.56 bisitz 691: text=>"Course/Community Catalog"});
1.19 raeburn 692: }
1.60 raeburn 693: my $brtextone = 'Course listing';
694: my $brtexttwo = 'Course details';
1.89 raeburn 695: my $textthree = &mt('Detailed course information:');
696: my $textfour = &mt('Back to course listing');
1.60 raeburn 697: if ($env{'form.currcat_0'} eq 'communities::0') {
698: $brtextone = 'Community listing';
1.61 raeburn 699: $brtexttwo = 'Community details';
1.89 raeburn 700: $textthree = &mt('Detailed community information:');
701: $textfour = &mt('Back to community listing');
702: } elsif ($env{'form.currcat_0'} eq 'placement::0') {
703: $brtextone = 'Placement test listing';
704: $brtexttwo = 'Placement test details';
705: $textthree = &mt('Detailed placement test information:');
706: $textfour = &mt('Back to placement test listing');
1.60 raeburn 707: }
1.7 raeburn 708: &Apache::lonhtmlcommon::add_breadcrumb
1.19 raeburn 709: ({href=>"javascript:document.$formname.submit()",
1.60 raeburn 710: text=>$brtextone},
711: {text=>$brtexttwo});
1.78 bisitz 712: $r->print(
713: &Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog').
1.108 ! raeburn 714: '<div role="main">'.
1.89 raeburn 715: '<h2>'.$textthree.'</h2>'.
1.104 raeburn 716: &print_course_listing($codedom,undef,$trails,$allitems,undef,$codetitles,undef,$hostname).
1.78 bisitz 717: '<br />'.
718: '<form name="'.$formname.'" method="post" action="/adm/coursecatalog">'.
719: &Apache::lonhtmlcommon::actionbox([
1.89 raeburn 720: '<a href = "javascript:document.coursecatalog.submit()">'.$textfour.'</a>']).
1.78 bisitz 721: &Apache::lonhtmlcommon::echo_form_input(['coursenum','catalogfilter',
722: 'showdetails','courseid']).
1.108 ! raeburn 723: '</form></div>');
1.40 raeburn 724: return;
725: }
726:
1.82 raeburn 727: sub coursesearch {
728: my ($codedom,$domdesc,$uniquecode) = @_;
729: my %lt = &Apache::lonlocal::texthash (
730: crlk => 'Course look-up',
731: code => 'Code',
1.84 raeburn 732: ifyo => 'Enter the course code (six letters and numbers)',
1.82 raeburn 733: srch => 'Find course',
734: );
735: return <<"END";
736: <h3>$lt{'crlk'} ($domdesc)</h3>
737: $lt{'ifyo'}
738: <form name="searchbycode" method="post" action="">
739: <span class="LC_nobreak">
740: <input type="text" value="$uniquecode" size="6" name="uniquecode" />
741: <br />
742: <input type="submit" value="$lt{'srch'}" name="srch" /></span>
743: </form>
744: END
745: }
746:
1.41 raeburn 747: sub courselink_javascript {
1.103 raeburn 748: my ($hostname) = @_;
1.40 raeburn 749: return <<"END";
750:
1.91 raeburn 751: function ToSyllabus(cdom,cnum,usehttp) {
1.40 raeburn 752: if (cdom == '' || cdom == null) {
753: return;
754: }
755: if (cnum == '' || cnum == null) {
756: return;
757: }
1.41 raeburn 758: document.linklaunch.action = "/public/"+cdom+"/"+cnum+"/syllabus";
1.91 raeburn 759: if (usehttp == 1) {
1.92 raeburn 760: var hostname = '$hostname';
761: if (hostname != '') {
762: document.linklaunch.action = 'http://'+hostname+document.linklaunch.action;
763: }
1.91 raeburn 764: document.linklaunch.action += '?usehttp=1';
765: }
1.41 raeburn 766: document.linklaunch.submit();
767: }
768:
769: function ToSelfenroll(courseid) {
770: if (courseid == '') {
771: return;
772: }
773: document.linklaunch.action = "/adm/selfenroll";
774: document.linklaunch.courseid.value = courseid;
775: document.linklaunch.submit();
1.40 raeburn 776: }
777:
778: END
1.7 raeburn 779: }
780:
1.28 raeburn 781: sub instcode_course_selector {
1.86 raeburn 782: my ($r,$codedom,$formname,$domdesc,$catlinks,$catjs,$codetitles,$cattype,$canviewall) = @_;
1.1 raeburn 783: my %cat_titles = ();
784: my %cat_order = ();
1.102 raeburn 785: my %cat_items = ();
1.30 raeburn 786: my %add_entries = (topmargin => "0",
787: marginheight => "0",);
1.51 raeburn 788: my ($jscript,$totcodes,$numtitles,$lasttitle) =
789: &Apache::courseclassifier::instcode_selectors_data($codedom,$formname,
1.63 raeburn 790: \%cat_items,$codetitles,\%cat_titles,\%cat_order);
1.80 bisitz 791: my $js = '<script type="text/javascript">'."\n".
1.79 raeburn 792: '// <![CDATA['."\n".
793: "$jscript\n$catjs\n".
794: '// ]]>'."\n".
795: '</script>';
1.51 raeburn 796: if ($totcodes) {
1.18 raeburn 797: if (($env{'form.state'} eq 'listing') && ($numtitles > 0)) {
1.87 raeburn 798: $add_entries{'onload'} = 'setElements();';
1.72 raeburn 799: }
1.86 raeburn 800: if (&user_is_dc($codedom) || $canviewall) {
1.87 raeburn 801: $add_entries{'onload'} .= ' toggleStatuses();toggleWasActive();'
1.7 raeburn 802: }
1.82 raeburn 803: &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles,$cattype);
1.28 raeburn 804: my $cat_maxdepth = $env{'form.catalog_maxdepth'};
805: $r->print('<form name="'.$formname.'" method="post" action="/adm/coursecatalog">'.
1.32 raeburn 806: '<input type="hidden" name="catalog_maxdepth" value="'.$cat_maxdepth.'" />'."\n".
807: '<input type="hidden" name="showdom" value="'.$env{'form.showdom'}.'" />'."\n".
808: '<input type="hidden" name="currcat_0" value="instcode::0" />'.
1.86 raeburn 809: &additional_filters($codedom,undef,$canviewall));
1.1 raeburn 810: if ($numtitles > 0) {
1.51 raeburn 811: $r->print('<b>'.&mt('Choose which course(s) to list.').'</b><br />'.
812: &Apache::courseclassifier::build_instcode_selectors($numtitles,
1.63 raeburn 813: $lasttitle,\%cat_items,$codetitles,\%cat_titles,\%cat_order));
1.18 raeburn 814: }
1.33 raeburn 815: $r->print('<input type="hidden" name="coursenum" value="" />'."\n".
816: '<input type="hidden" name="sortby" value="" />'."\n".
817: '<input type="hidden" name="state" value="listing" />'."\n".
818: '<input type="submit" name="catalogfilter" value="'.
819: &mt('Display courses').'" />'.
820: '<input type="hidden" name="numtitles" value="'.$numtitles.
1.37 raeburn 821: '" /></form><br /><br />');
1.5 raeburn 822: } else {
1.81 raeburn 823: $js = '<script type="text/javascript">'."\n".
824: '// <![CDATA['."\n".
825: "$catjs\n".
826: '// ]]>'."\n".
827: '</script>';
1.82 raeburn 828: &cat_header($r,$codedom,$js,\%add_entries,$catlinks,$numtitles,$cattype);
1.30 raeburn 829: my $cat_maxdepth = $env{'form.catalog_maxdepth'};
830: $r->print('<form name="'.$formname.'" method="post" action="/adm/coursecatalog">'.
831: '<input type="hidden" name="catalog_maxdepth" value="'.$cat_maxdepth.'" />'.
832: '<input type="hidden" name="showdom" value="'.$env{'form.showdom'}.'" />'.
833: '<input type="hidden" name="currcat_0" value="instcode::0" />');
834: $r->print('<br />'.&mt('No official courses to display for [_1].',$domdesc).'</form>');
1.1 raeburn 835: }
1.18 raeburn 836: return $numtitles;
1.1 raeburn 837: }
838:
1.28 raeburn 839: sub cat_header {
1.82 raeburn 840: my ($r,$codedom,$js,$add_entries,$catlinks,$numtitles,$cattype) = @_;
1.28 raeburn 841: my $start_page =
1.72 raeburn 842: &Apache::loncommon::start_page('Course/Community Catalog',$js,
1.59 droeschl 843: { 'add_entries' => $add_entries, });
1.28 raeburn 844: $r->print($start_page);
1.60 raeburn 845: my $brtext = 'Course listing';
846: if ($env{'form.currcat_0'} eq 'communities::0') {
847: $brtext = 'Community listing';
1.89 raeburn 848: } elsif ($env{'form.currcat_0'} eq 'placement::0') {
849: $brtext = 'Placement test listing';
1.60 raeburn 850: }
1.28 raeburn 851: if ($env{'form.state'} eq 'listing') {
852: if ($numtitles > 0) {
853: &Apache::lonhtmlcommon::add_breadcrumb
854: ({href=>"/adm/coursecatalog",
1.56 bisitz 855: text=>"Course/Community Catalog"},
1.60 raeburn 856: {text=>$brtext});
1.28 raeburn 857: } else {
858: &Apache::lonhtmlcommon::add_breadcrumb
1.60 raeburn 859: ({text=>$brtext});
1.28 raeburn 860: }
861: } else {
862: &Apache::lonhtmlcommon::add_breadcrumb
863: ({href=>"/adm/coursecatalog",
1.56 bisitz 864: text=>"Course/Community Catalog"});
1.28 raeburn 865: }
1.108 ! raeburn 866: $r->print(&Apache::lonhtmlcommon::breadcrumbs('Course/Community Catalog').
! 867: '<div role="main">');
1.82 raeburn 868: if ($cattype eq 'std') {
869: $r->print('<form name="coursecatdom" method="post" action="/adm/coursecatalog">'.
1.108 ! raeburn 870: '<table border="0"><tr><th align="left"><label for="showdom">'.&mt('Domain:').'</label></th><td>'.
! 871: &Apache::loncommon::select_dom_form($codedom,'showdom','',1,'','','','','showdom').
! 872: ' <input type="submit" name="godom" value="'.&mt('Change').'" />'."\n".
! 873: '<input type="hidden" name="initialshowdom" value="'.$codedom.'" />'."\n".
! 874: '</td></tr></table></form>');
! 875: }
! 876: my $onsubmit;
! 877: unless ($env{'form.currcat_0'} eq 'instcode::0') {
! 878: $onsubmit = ' onsubmit="return check_selected();"';
1.47 raeburn 879: }
1.108 ! raeburn 880: $r->print('<form name="coursecats" method="post" action="/adm/coursecatalog"'.$onsubmit.'>'.
1.34 raeburn 881: '<table border="0"><tr>'.$catlinks.'</tr></table></form>');
1.28 raeburn 882: return;
883: }
884:
885: sub category_breadcrumbs {
1.35 raeburn 886: my ($dom,@cats) = @_;
1.44 raeburn 887: my $crumbsymbol = ' ▶ ';
1.33 raeburn 888: my ($currdepth,$deeper) = &get_depth_values();
1.57 raeburn 889: my $currcat_str =
890: '<input type="hidden" name="catalog_maxdepth" value="'.$deeper.'" />'.
891: '<input type="hidden" name="showdom" value="'.$dom.'" />';
1.108 ! raeburn 892: my $catlinks = '<th class="LC_middle LC_left">'.&mt('Catalog:').'</th><td><div class="LC_leftfloat">';
1.36 raeburn 893: my $has_subcats;
1.46 raeburn 894: my $selitem;
1.108 ! raeburn 895: my $update_button;
1.58 raeburn 896: if (ref($cats[0]) eq 'ARRAY') {
897: if (@{$cats[0]} == 0) {
898: $catlinks .= &mt('No categories defined in this domain');
899: } elsif (@{$cats[0]} == 1) {
900: if ($cats[0][0] eq 'instcode') {
901: $catlinks .= &mt('Official courses (with institutional codes)');
902: $env{'form.currcat_0'} = 'instcode::0';
903: } elsif ($cats[0][0] eq 'communities') {
904: $catlinks .= &mt('Communities');
905: $env{'form.currcat_0'} = 'communities::0';
1.89 raeburn 906: } elsif ($cats[0][0] eq 'placement') {
907: $catlinks .= &mt('Placement Tests');
908: $env{'form.currcat_0'} = 'placement::0';
1.58 raeburn 909: } else {
910: my $name = $cats[0][0];
911: my $item = &escape($name).'::0';
912: $catlinks .= $name;
913: $env{'form.currcat_0'} = $item;
1.46 raeburn 914: }
1.58 raeburn 915: $currcat_str .= '<input type="hidden" name="currcat_0" value="'.$env{'form.currcat_0'}.'" />';
1.28 raeburn 916: } else {
1.108 ! raeburn 917: $update_button = 1;
1.58 raeburn 918: $catlinks .= &main_category_selector(@cats);
919: if (($env{'form.currcat_0'} ne '') &&
920: ($env{'form.currcat_0'} ne 'instcode::0')) {
921: $catlinks .= $crumbsymbol;
922: }
923: }
924: } else {
925: $catlinks .= &mt('Official courses (with institutional codes)');
926: $env{'form.currcat_0'} = 'instcode::0';
1.108 ! raeburn 927: $currcat_str .= '<input type="hidden" name="currcat_0" value="'.$env{'form.currcat_0'}.'" />';
1.58 raeburn 928: }
929: if ($deeper) {
930: for (my $i=1; $i<=$deeper; $i++) {
931: my $shallower = $i-1;
932: next if ($shallower == 0);
1.28 raeburn 933: my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$env{'form.currcat_'.$shallower});
1.58 raeburn 934: if ($cat ne '') {
1.108 ! raeburn 935: my $labeltext = &HTML::Entities::encode(&mt('Level [_1] category',$shallower),'<>&"');
! 936: $catlinks .= '<select name="currcat_'.$shallower.'" aria-label="'.$labeltext.'">';
1.58 raeburn 937: if (ref($cats[$shallower]{$container}) eq 'ARRAY') {
1.108 ! raeburn 938: $catlinks .= '<option value="-1">'.&mt('De-select').'</option>';
1.58 raeburn 939: for (my $j=0; $j<@{$cats[$shallower]{$container}}; $j++) {
940: my $name = $cats[$shallower]{$container}[$j];
1.65 raeburn 941: my $item = &escape($name).':'.&escape($container).':'.$shallower;
1.58 raeburn 942: my $selected = '';
943: if ($item eq $env{'form.currcat_'.$shallower}) {
944: $selected = ' selected="selected"';
945: }
946: $catlinks .=
947: '<option value="'.$item.'"'.$selected.'>'.$name.'</option>';
1.28 raeburn 948: }
949: }
1.108 ! raeburn 950: $catlinks .= '</select>'.
! 951: '<input type="hidden" name="initialcurrcat_'.$shallower.'" value="'.$env{'form.currcat_'.$shallower}.'" />';
1.28 raeburn 952: }
1.58 raeburn 953: unless ($i == $deeper) {
954: $catlinks .= $crumbsymbol;
955: }
1.28 raeburn 956: }
1.29 raeburn 957: my ($cat,$container,$depth);
958: if ($env{'form.currcat_'.$currdepth} eq '') {
959: my $shallower = $currdepth - 1;
960: ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$env{'form.currcat_'.$shallower});
961: } else {
962: ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$env{'form.currcat_'.$currdepth});
963: }
1.58 raeburn 964: my $deeperlevel = $depth +1;
965: if (ref($cats[$deeperlevel]{$cat}) eq 'ARRAY') {
1.36 raeburn 966: $has_subcats = 1;
1.46 raeburn 967: my $buttontext = &mt('Show subcategories');
1.58 raeburn 968: my $selitem = 'currcat_'.$deeperlevel;
1.108 ! raeburn 969: my $labeltext = &HTML::Entities::encode(&mt('Level [_1] category',$deeperlevel),'<>&"');
! 970: $catlinks .= ' <select name="'.$selitem.'" aria-label="'.$labeltext.'">';
1.58 raeburn 971: if (@{$cats[$deeperlevel]{$cat}}) {
1.46 raeburn 972: $catlinks .= '<option value="" selected="selected">'.
1.58 raeburn 973: &mt('Subcategory ...').'</option>';
1.46 raeburn 974: }
1.58 raeburn 975: for (my $k=0; $k<@{$cats[$deeperlevel]{$cat}}; $k++) {
976: my $name = $cats[$deeperlevel]{$cat}[$k];
977: my $item = &escape($name).':'.&escape($cat).':'.$deeperlevel;
1.28 raeburn 978: $catlinks .= '<option value="'.$item.'">'.$name.'</option>'."\n";
979: }
1.58 raeburn 980: $catlinks .= '</select>'."\n";
1.46 raeburn 981: } elsif ($cat ne 'instcode') {
982: $catlinks .= ' '.&mt('(No subcategories)');
1.28 raeburn 983: }
1.58 raeburn 984: } else {
985: $selitem = 'currcat_0';
1.28 raeburn 986: }
1.108 ! raeburn 987: $catlinks .= $currcat_str;
! 988: if ($update_button) {
! 989: $catlinks .= ' <input type="submit" name="gocat" value="'.&mt('Update').'" />'."\n";
! 990: }
! 991: $catlinks .= '</div></td>';
1.46 raeburn 992: return ($catlinks,$has_subcats,$selitem);
1.28 raeburn 993: }
994:
1.58 raeburn 995: sub main_category_selector {
996: my (@cats) = @_;
1.108 ! raeburn 997: my $labeltext = &HTML::Entities::encode(&mt('Top level category'),'<>&"');
! 998: my $maincatlinks = '<select name="currcat_0" aria-label="'.$labeltext.'">'."\n";
1.58 raeburn 999: if (ref($cats[0]) eq 'ARRAY') {
1000: if (@{$cats[0]} > 1) {
1001: my $selected = '';
1002: if ($env{'form.currcat_0'} eq '') {
1003: $selected = ' selected="selected"';
1004: }
1005: $maincatlinks .=
1006: '<option value=""'.$selected.'>'.&mt('Select').'</option>'."\n";
1007: }
1008: for (my $i=0; $i<@{$cats[0]}; $i++) {
1009: my $name = $cats[0][$i];
1010: my $item = &escape($name).'::0';
1011: my $selected;
1012: if ($env{'form.currcat_0'} eq $item) {
1013: $selected = ' selected="selected"';
1014: }
1015: $maincatlinks .= '<option value="'.$item.'"'.$selected.'>';
1016: if ($name eq 'instcode') {
1017: $maincatlinks .= &mt('Official courses (with institutional codes)');
1018: } elsif ($name eq 'communities') {
1019: $maincatlinks .= &mt('Communities');
1.89 raeburn 1020: } elsif ($name eq 'placement') {
1021: $maincatlinks .= &mt('Placement Tests');
1.58 raeburn 1022: } else {
1023: $maincatlinks .= $name;
1024: }
1025: $maincatlinks .= '</option>'."\n";
1026: }
1.108 ! raeburn 1027: $maincatlinks .= '</select>'."\n".
! 1028: '<input type="hidden" name="initialcurrcat_0" value="'.$env{'form.currcat_0'}.'" />'."\n";
1.58 raeburn 1029: }
1030: return $maincatlinks;
1031: }
1032:
1.33 raeburn 1033: sub get_depth_values {
1034: my $currdepth = 0;
1035: my $deeper = 0;
1036: if ($env{'form.catalog_maxdepth'} ne '') {
1037: $currdepth = $env{'form.catalog_maxdepth'};
1038: if ($env{'form.currcat_'.$currdepth} eq '') {
1039: $deeper = $currdepth;
1040: } else {
1041: $deeper = $currdepth + 1;
1042: }
1043: }
1044: return ($currdepth,$deeper);
1045: }
1046:
1047: sub additional_filters {
1.86 raeburn 1048: my ($codedom,$has_subcats,$canviewall) = @_;
1.72 raeburn 1049: my $is_dc = &user_is_dc($codedom);
1050: my $output = '<div class="LC_left_float">';
1.86 raeburn 1051: if ($is_dc || $canviewall) {
1.72 raeburn 1052: $output .= '<fieldset><legend>'.&mt('Options').'</legend>';
1053: }
1.108 ! raeburn 1054: $output .= '<div class="LC_floatleft" style="text-align: top">';
1.72 raeburn 1055: if (($env{'form.currcat_0'} ne 'instcode::0') &&
1.36 raeburn 1056: ($env{'form.currcat_0'} ne '') && ($has_subcats)) {
1057: my $include_subcat_status;
1058: if ($env{'form.withsubcats'}) {
1059: $include_subcat_status = 'checked="checked" ';
1060: }
1061: my $counter = $env{'form.catalog_maxdepth'};
1062: if ($counter > 0) {
1063: if ($env{'form.state'} eq 'listing') {
1064: $counter --;
1065: } elsif ($env{'form.currcat_'.$counter} eq '') {
1066: $counter --;
1067: }
1068: }
1069: my ($catname) = split(/:/,$env{'form.currcat_'.$counter});
1070: if ($catname ne '') {
1.72 raeburn 1071: $output .= '<span class="LC_nobreak"><label>'.
1.36 raeburn 1072: '<input type="checkbox" name="withsubcats" value="1" '.
1073: $include_subcat_status.'/>'.
1.38 raeburn 1074: &mt('Include subcategories within "[_1]"',
1.72 raeburn 1075: &unescape($catname)).'</label></span><br />';
1.36 raeburn 1076: }
1077: }
1.33 raeburn 1078: my $show_selfenroll_status;
1079: if ($env{'form.showselfenroll'}) {
1080: $show_selfenroll_status = 'checked="checked" ';
1081: }
1.57 raeburn 1082: my $selfenroll_text;
1083: if ($env{'form.currcat_0'} eq 'communities::0') {
1.69 raeburn 1084: $selfenroll_text = &mt('Only show communities which currently allow self-enrollment (or will allow it in the future)');
1.89 raeburn 1085: } elsif ($env{'form.currcat_0'} eq 'placement::0') {
1086: $selfenroll_text = &mt('Only show placement tests which currently allow self-enrollment (or will allow it in the future)');
1.57 raeburn 1087: } else {
1.69 raeburn 1088: $selfenroll_text = &mt('Only show courses which currently allow self-enrollment (or will allow it in the future)');
1.57 raeburn 1089: }
1.72 raeburn 1090: $output .= '<span class="LC_nobreak">'.
1.36 raeburn 1091: '<label><input type="checkbox" name="showselfenroll" value="1" '.
1.57 raeburn 1092: $show_selfenroll_status.'/>'.$selfenroll_text.
1.72 raeburn 1093: '</label></span><br />';
1.86 raeburn 1094: if ($is_dc || $canviewall) {
1.72 raeburn 1095: my ($titlesref,$orderref) = &get_statustitles('filters');
1.33 raeburn 1096: my $showdetails_status;
1097: if ($env{'form.showdetails'}) {
1098: $showdetails_status = 'checked="checked" ';
1099: }
1100: my $showhidden_status;
1101: if ($env{'form.showhidden'}) {
1.72 raeburn 1102: $showhidden_status = 'checked="checked" ';
1.33 raeburn 1103: }
1.72 raeburn 1104: my @currstatuses = &Apache::loncommon::get_env_multiple('form.showcounts');
1105: my ($details_text,$hidden_text,$statusdisplay,$cellborder);
1106: my $wasactivedisplay = 'none';
1107: if ($env{'form.showdetails'}) {
1108: $statusdisplay = 'block';
1109: $cellborder = 'border-left: 1px solid;';
1110: if (grep(/^Previous$/,@currstatuses)) {
1111: $wasactivedisplay = 'block';
1112: }
1113: } else {
1114: $statusdisplay = 'none';
1.108 ! raeburn 1115: $cellborder = 'border-left: 0px;';
1.72 raeburn 1116: }
1.108 ! raeburn 1117: $cellborder .= ' vertical-align: top;';
1.57 raeburn 1118: if ($env{'form.currcat_0'} eq 'communities::0') {
1.90 raeburn 1119: $details_text = &mt('Show full details for each community (domain staff only)');
1120: $hidden_text = &mt('Include communities set to be hidden from catalog (domain staff only)');
1.89 raeburn 1121: } elsif ($env{'form.currcat_0'} eq 'placement::0') {
1.90 raeburn 1122: $details_text = &mt('Show full details for each placement test (domain staff only)');
1123: $hidden_text = &mt('Include placement tests set to be hidden from catalog (domain staff only)');
1.57 raeburn 1124: } else {
1.90 raeburn 1125: $details_text = &mt('Show full details for each course (domain staff only)');
1126: $hidden_text = &mt('Include courses set to be hidden from catalog (domain staff only)');
1.57 raeburn 1127: }
1.86 raeburn 1128: if ($is_dc) {
1129: $output .= '<span class="LC_nobreak">'.
1130: '<label><input type="checkbox" name="showhidden" value="1" '.
1131: $showhidden_status.'/>'.$hidden_text.
1132: '</label></span><br />'."\n";
1133: }
1.72 raeburn 1134: $output .= '<span class="LC_nobreak">'.
1135: '<label><input type="checkbox" name="showdetails" value="1" '.
1136: $showdetails_status.'onclick="toggleStatuses();" />'.
1.108 ! raeburn 1137: $details_text.'</label></span></div>'."\n".
! 1138: '<div class="LC_floatleft" id="statuscell" style="'.$cellborder.'">'.
! 1139: '<div class="LC_floatleft" id="statuschoice" style="display:'.$statusdisplay.'; margin-left: 10px">';
1.72 raeburn 1140: if (ref($orderref) eq 'ARRAY') {
1141: if (@{$orderref} > 0) {
1142: foreach my $type (@{$orderref}) {
1143: my $checked;
1144: if (grep(/^\Q$type\E$/,@currstatuses)) {
1145: $checked = ' checked="checked"';
1146: }
1147: my $title;
1148: if (ref($titlesref) eq 'HASH') {
1149: $title = $titlesref->{$type};
1150: }
1151: unless ($title) {
1152: $title = &mt($type);
1153: }
1154: my $onclick;
1155: if ($type eq 'Previous') {
1156: $onclick = ' onclick="toggleWasActive();"';
1157: }
1158: $output .= '<span class="LC_nobreak">'.
1159: '<label><input type="checkbox" id="counts_'.$type.'"'.
1160: ' name="showcounts" value="'.$type.'"'.$checked.$onclick.
1161: ' />'.$title.'</label></span>';
1162: if ($type eq 'Previous') {
1163: my %milestonetext = &Apache::lonlocal::texthash (
1.74 raeburn 1164: accessend => 'immediately prior to default end access date',
1165: enrollend => 'immediately prior to end date for auto-enrollment',
1166: date => 'immediately prior to specific date:',
1.72 raeburn 1167: );
1168: my @statuses = &Apache::loncommon::get_env_multiple('form.showcounts');
1.108 ! raeburn 1169: my $wasactivetext;
1.72 raeburn 1170: if ($checked) {
1.108 ! raeburn 1171: $wasactivetext = &get_wasactive_text();
1.72 raeburn 1172: }
1.108 ! raeburn 1173: $output .= '<div id="choosewasactive" style="display:'.$wasactivedisplay.'">'."\n".
! 1174: '<fieldset style="margin-left: 4px">'."\n".
! 1175: '<legend id="choosewasacctext" style="font-weight: normal">'."\n".
! 1176: $wasactivetext.'</legend>'."\n";
1.72 raeburn 1177: my @milestones = ('accessend');
1178: if (&Apache::lonnet::auto_run(undef,$codedom)) {
1179: push(@milestones,'enrollend');
1180: }
1181: push(@milestones,'date');
1182: foreach my $item (@milestones) {
1183: my $checked;
1184: if ($env{'form.state'} eq 'listing') {
1185: if ($env{'form.wasactive'} eq $item) {
1186: $checked = ' checked="checked"';
1187: }
1188: } elsif ($item eq 'accessend') {
1189: $checked = ' checked="checked"';
1190: }
1191: $output .=
1.108 ! raeburn 1192: '<span class="LC_nobreak" style="padding-left:10px;"><label>'.
1.72 raeburn 1193: '<input type="radio" value="'.$item.'" name="wasactive"'.$checked.' />'.
1194: $milestonetext{$item}.'</label></span>';
1195: if ($item eq 'date') {
1196: my $wasactiveon;
1197: if (grep(/^Previous$/,@currstatuses)) {
1198: $wasactiveon =
1199: &Apache::lonhtmlcommon::get_date_from_form('wasactiveon');
1200: } else {
1201: $wasactiveon = 'now';
1202: }
1203: $output .= ' '.
1204: &Apache::lonhtmlcommon::date_setter('coursecatalog',
1205: 'wasactiveon',
1206: $wasactiveon,
1207: '','','',1,'',
1208: '','',1);
1209: }
1.108 ! raeburn 1210: $output .= '<br />';
1.72 raeburn 1211: }
1.108 ! raeburn 1212: $output .= '</fieldset></div>';
1.72 raeburn 1213: }
1214: $output .= '<br />';
1215: }
1216: }
1217: }
1.108 ! raeburn 1218: $output .= '</div></div>';
1.72 raeburn 1219: } else {
1.108 ! raeburn 1220: $output .= '</div>';
1.33 raeburn 1221: }
1.108 ! raeburn 1222: $output .= '</fieldset></div>'.
1.72 raeburn 1223: '<div style="clear:both;margin:0;"></div>';
1.33 raeburn 1224: return $output;
1225: }
1226:
1.16 raeburn 1227: sub user_is_dc {
1228: my ($codedom) = @_;
1229: if (exists($env{'user.role.dc./'.$codedom.'/'})) {
1230: my $livedc = 1;
1231: my $now = time;
1232: my ($start,$end)=split(/\./,$env{'user.role.dc./'.$codedom.'/'});
1233: if ($start && $start>$now) { $livedc = 0; }
1234: if ($end && $end <$now) { $livedc = 0; }
1235: return $livedc;
1236: }
1237: return;
1238: }
1.7 raeburn 1239:
1.86 raeburn 1240: sub canview_all {
1.90 raeburn 1241: my ($knownuser,$codedom) = @_;
1.86 raeburn 1242: my $canviewall = 0;
1243: my $page = 'coursecatalog';
1244: if (&LONCAPA::lonauthcgi::can_view($page)) {
1245: $canviewall = 1;
1246: } elsif (&LONCAPA::lonauthcgi::check_ipbased_access($page)) {
1247: $canviewall= 1;
1.90 raeburn 1248: } elsif (($knownuser) && ($codedom ne '')) {
1249: if (&Apache::lonnet::allowed('dcd',$codedom)) {
1250: $canviewall = 1;
1251: }
1.86 raeburn 1252: }
1253: return $canviewall;
1254: }
1255:
1.72 raeburn 1256: sub get_statustitles {
1257: my ($caller) = @_;
1258: my @status_order = ('Active','Future','Previous');
1259: my %status_title;
1260: if ($caller eq 'filters') {
1261: %status_title = &Apache::lonlocal::texthash(
1262: Previous => 'Show count for past access',
1263: Active => 'Show count for current student access',
1264: Future => 'Show count for future student access',
1265: );
1266: if ($env{'form.currcat_0'} eq 'communities::0') {
1267: $status_title{'Active'} = 'Show count for current member access';
1268: $status_title{'Future'} = 'Show count for future member access';
1269: }
1270: } else {
1271: %status_title = &Apache::lonlocal::texthash(
1272: Previous => 'Previous access',
1273: Active => 'Current access',
1274: Future => 'Future access',
1275: );
1276: }
1277: return (\%status_title,\@status_order);
1278: }
1279:
1280: sub get_wasactive_text {
1.108 ! raeburn 1281: my $wasacctext;
1.72 raeburn 1282: if ($env{'form.currcat_0'} eq 'communities::0') {
1.108 ! raeburn 1283: $wasacctext .= &mt('count where member access status was current ...');
1.72 raeburn 1284: } else {
1.108 ! raeburn 1285: $wasacctext .= &mt('count where student access status was current ...');
1.72 raeburn 1286: }
1287: return $wasacctext;
1288: }
1289:
1.28 raeburn 1290: sub search_official_courselist {
1.63 raeburn 1291: my ($domain,$numtitles,$codetitles) = @_;
1292: my $instcode = &Apache::courseclassifier::instcode_search_str($domain,$numtitles,$codetitles);
1.32 raeburn 1293: my $showhidden;
1294: if (&user_is_dc($domain)) {
1295: $showhidden = $env{'form.showhidden'};
1296: }
1297: my %courses =
1298: &Apache::lonnet::courseiddump($domain,'.',1,$instcode,'.','.',undef,undef,
1299: 'Course',1,$env{'form.showselfenroll'},undef,
1300: $showhidden,'coursecatalog');
1.7 raeburn 1301: return %courses;
1302: }
1303:
1.28 raeburn 1304: sub search_courselist {
1.36 raeburn 1305: my ($domain,$subcats) = @_;
1.28 raeburn 1306: my $cat_maxdepth = $env{'form.catalog_maxdepth'};
1307: my $filter = $env{'form.currcat_'.$cat_maxdepth};
1.29 raeburn 1308: if (($filter eq '') && ($cat_maxdepth > 0)) {
1309: my $shallower = $cat_maxdepth - 1;
1310: $filter = $env{'form.currcat_'.$shallower};
1311: }
1.28 raeburn 1312: my %courses;
1.36 raeburn 1313: my $filterstr;
1.28 raeburn 1314: if ($filter ne '') {
1.36 raeburn 1315: if ($env{'form.withsubcats'}) {
1316: if (ref($subcats) eq 'HASH') {
1317: if (ref($subcats->{$filter}) eq 'ARRAY') {
1318: $filterstr = join('&',@{$subcats->{$filter}});
1319: if ($filterstr ne '') {
1320: $filterstr = $filter.'&'.$filterstr;
1321: }
1322: } else {
1323: $filterstr = $filter;
1324: }
1325: } else {
1326: $filterstr = $filter;
1327: }
1328: } else {
1329: $filterstr = $filter;
1330: }
1.57 raeburn 1331: my ($showhidden,$typefilter);
1.32 raeburn 1332: if (&user_is_dc($domain)) {
1333: $showhidden = $env{'form.showhidden'};
1334: }
1.57 raeburn 1335: if ($env{'form.currcat_0'} eq 'communities::0') {
1336: $typefilter = 'Community';
1.89 raeburn 1337: } elsif ($env{'form.currcat_0'} eq 'placement::0') {
1338: $typefilter = 'Placement';
1.57 raeburn 1339: } else {
1340: $typefilter = '.';
1341: }
1.32 raeburn 1342: %courses =
1343: &Apache::lonnet::courseiddump($domain,'.',1,'.','.','.',undef,undef,
1.57 raeburn 1344: $typefilter,1,$env{'form.showselfenroll'},
1.36 raeburn 1345: $filterstr,$showhidden,'coursecatalog');
1.28 raeburn 1346: }
1347: return %courses;
1348: }
1.6 raeburn 1349:
1.1 raeburn 1350: sub print_course_listing {
1.104 raeburn 1351: my ($domain,$numtitles,$trails,$allitems,$subcats,$codetitles,$canviewall,$hostname) = @_;
1.1 raeburn 1352: my $output;
1.7 raeburn 1353: my %courses;
1.15 raeburn 1354: my $knownuser = &user_is_known();
1.86 raeburn 1355: my $canviewall = &canview_all();
1.16 raeburn 1356: my $details = $env{'form.coursenum'};
1.86 raeburn 1357: if (&user_is_dc($domain) || $canviewall) {
1.16 raeburn 1358: if ($env{'form.showdetails'}) {
1359: $details = 1;
1360: }
1361: }
1.7 raeburn 1362: if ($env{'form.coursenum'} ne '') {
1363: %courses = &Apache::lonnet::courseiddump($domain,'.',1,'.','.',
1364: $env{'form.coursenum'},
1.33 raeburn 1365: undef,undef,'.',1);
1.7 raeburn 1366: if (keys(%courses) == 0) {
1.78 bisitz 1367: $output = '<p class="LC_error">';
1.60 raeburn 1368: if ($env{'form.currcat_0'} eq 'communities::0') {
1369: $output .= &mt('The courseID provided does not match a community in this domain.');
1.89 raeburn 1370: } elsif ($env{'form.currcat_0'} eq 'placement::0') {
1371: $output .= &mt('The courseID provided does not match a placement test in this domain.');
1372: } else {
1.60 raeburn 1373: $output .= &mt('The courseID provided does not match a course in this domain.');
1374: }
1.78 bisitz 1375: $output .= '</p>';
1.7 raeburn 1376: return $output;
1377: }
1.6 raeburn 1378: } else {
1.28 raeburn 1379: if ($env{'form.currcat_0'} eq 'instcode::0') {
1.63 raeburn 1380: %courses = &search_official_courselist($domain,$numtitles,$codetitles);
1.28 raeburn 1381: } else {
1.36 raeburn 1382: %courses = &search_courselist($domain,$subcats);
1.28 raeburn 1383: }
1.7 raeburn 1384: if (keys(%courses) == 0) {
1.78 bisitz 1385: $output = '<p class="LC_info">';
1.57 raeburn 1386: if ($env{'form.currcat_0'} eq 'communities::0') {
1.78 bisitz 1387: $output .= &mt('No communities match the criteria you selected.');
1.89 raeburn 1388: } elsif ($env{'form.currcat_0'} eq 'placement::0') {
1389: $output .= &mt('No placement tests match the criteria you selected.');
1.57 raeburn 1390: } else {
1.78 bisitz 1391: $output .= &mt('No courses match the criteria you selected.');
1.57 raeburn 1392: }
1.78 bisitz 1393: $output .= '</p>';
1.7 raeburn 1394: return $output;
1395: }
1.86 raeburn 1396: if (($knownuser) && (!$env{'form.showdetails'}) && (!&user_is_dc($domain)) && (!$canviewall)) {
1.31 bisitz 1397: $output = '<b>'.&mt('Note for students:').'</b> '
1398: .&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.')
1399: .'<br /><br />';
1.8 raeburn 1400: }
1.7 raeburn 1401: }
1.27 raeburn 1402: my $now = time;
1.72 raeburn 1403: $output .= &construct_data_table($knownuser,$domain,\%courses,$details,undef,
1.104 raeburn 1404: $now,$trails,$allitems,$canviewall,$hostname);
1.41 raeburn 1405: $output .= "\n".'<form name="linklaunch" method="post" action="">'.
1.40 raeburn 1406: '<input type="hidden" name="backto" value="coursecatalog" />'.
1.41 raeburn 1407: '<input type="hidden" name="courseid" value="" />'.
1408: &Apache::lonhtmlcommon::echo_form_input(['catalogfilter','courseid']).'</form>';
1.15 raeburn 1409: return $output;
1410: }
1411:
1412: sub construct_data_table {
1.104 raeburn 1413: my ($knownuser,$domain,$courses,$details,$usersections,$now,
1414: $trails,$allitems,$canviewall,$hostname) = @_;
1.7 raeburn 1415: my %sortname;
1.16 raeburn 1416: if (($details eq '') || ($env{'form.showdetails'})) {
1.7 raeburn 1417: $sortname{'Code'} = 'code';
1.35 raeburn 1418: $sortname{'Categories'} = 'cats';
1.7 raeburn 1419: $sortname{'Title'} = 'title';
1.70 raeburn 1420: $sortname{'Owner & Co-owner(s)'} = 'owner';
1.7 raeburn 1421: }
1.15 raeburn 1422: my $output = &Apache::loncommon::start_data_table().
1423: &Apache::loncommon::start_data_table_header_row();
1.35 raeburn 1424: my @coltitles = ('Count');
1425: if ($env{'form.currcat_0'} eq 'instcode::0') {
1426: push(@coltitles,'Code');
1427: } else {
1428: push(@coltitles,'Categories');
1429: }
1.70 raeburn 1430: push(@coltitles,('Sections','Crosslisted','Title','Owner & Co-owner(s)'));
1.15 raeburn 1431: if (ref($usersections) eq 'HASH') {
1432: $coltitles[1] = 'Your Section';
1433: }
1.7 raeburn 1434: foreach my $item (@coltitles) {
1435: $output .= '<th>';
1436: if (defined($sortname{$item})) {
1437: $output .= '<a href="javascript:changeSort('."'$sortname{$item}'".')">'.&mt($item).'</a>';
1.24 raeburn 1438: } elsif ($item eq 'Count') {
1.108 ! raeburn 1439: $output .= '#';
1.7 raeburn 1440: } else {
1441: $output .= &mt($item);
1442: }
1443: $output .= '</th>';
1.1 raeburn 1444: }
1.72 raeburn 1445: my (@fields,%fieldtitles,$wasactiveon);
1.86 raeburn 1446: if ($knownuser || ($canviewall && $details)) {
1.15 raeburn 1447: if ($details) {
1.60 raeburn 1448: if ($env{'form.currcat_0'} eq 'communities::0') {
1.72 raeburn 1449: $output .= '<th>'.&mt('Default Access Dates for Members').'</th>'.
1450: '<th>'.&mt('Member Counts').'</th>';
1.89 raeburn 1451: } elsif ($env{'form.currcat_0'} eq 'placement::0') {
1452: $output .=
1453: '<th>'.&mt('Default Access Dates for Students').'</th>'.
1454: '<th>'.&mt('Student Counts').'</th>';
1.60 raeburn 1455: } else {
1456: $output .=
1457: '<th>'.&mt('Default Access Dates for Students').'</th>'.
1458: '<th>'.&mt('Student Counts').'</th>'.
1459: '<th>'.&mt('Auto-enrollment of[_1]registered students','<br />').'</th>';
1460: }
1.72 raeburn 1461: my ($titlesref,$orderref) = &get_statustitles();
1462: my @statuses;
1.86 raeburn 1463: if (&user_is_dc($domain) || $canviewall) {
1.72 raeburn 1464: @statuses = &Apache::loncommon::get_env_multiple('form.showcounts');
1465: if (grep(/^Previous$/,@statuses)) {
1466: if ($env{'form.wasactive'} eq 'date') {
1467: $wasactiveon =
1468: &Apache::lonhtmlcommon::get_date_from_form('wasactiveon');
1469: } else {
1470: $wasactiveon = $env{'form.wasactive'};
1471: }
1472: }
1473: if (ref($orderref) eq 'ARRAY') {
1474: foreach my $status (@{$orderref}) {
1475: if (grep(/^\Q$status\E$/,@statuses)) {
1476: push(@fields,$status);
1477: }
1478: }
1479: }
1480: } else {
1481: @fields = ('Active','Future');
1482: }
1483: foreach my $status (@fields) {
1484: my $title;
1485: if (ref($titlesref) eq 'HASH') {
1486: $title = $titlesref->{$status};
1487: }
1488: unless ($title) {
1489: $title = &mt($status);
1490: }
1491: $fieldtitles{$status} = $title;
1492: }
1.15 raeburn 1493: } else {
1.27 raeburn 1494: $output .= '<th>'.&mt('Details').'</th>';
1.8 raeburn 1495: }
1.1 raeburn 1496: }
1.27 raeburn 1497: $output .= '<th>'.&mt('Self-enroll (if permitted)').'</th>';
1.7 raeburn 1498: &Apache::loncommon::end_data_table_header_row();
1.73 raeburn 1499: my (%numbers,%creditsum);
1.76 raeburn 1500: my ($showcredits,$defofficial,$defunofficial,$deftextbook);
1.73 raeburn 1501: my %domdefaults = &Apache::lonnet::get_domain_defaults($domain);
1.89 raeburn 1502: unless (($env{'form.currcat_0'} eq 'communities::0') || ($env{'form.currcat_0'} eq 'placement::0')) {
1.76 raeburn 1503: if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'} || $domdefaults{'textbookcredits'}) {
1.73 raeburn 1504: $showcredits = 1;
1505: $defofficial = $domdefaults{'officialcredits'};
1.76 raeburn 1506: $defunofficial = $domdefaults{'unofficialcredits'};
1507: $deftextbook = $domdefaults{'textbookcredits'};
1.73 raeburn 1508: }
1509: }
1.86 raeburn 1510: my %courseinfo = &build_courseinfo_hash($courses,$knownuser,$domain,$canviewall,$details,
1.72 raeburn 1511: $usersections,\@fields,\%fieldtitles,
1.73 raeburn 1512: $wasactiveon,\%numbers,\%creditsum,
1.76 raeburn 1513: $showcredits,$defofficial,$defunofficial,$deftextbook);
1.7 raeburn 1514: my %Sortby;
1.15 raeburn 1515: foreach my $course (sort(keys(%{$courses}))) {
1.7 raeburn 1516: if ($env{'form.sortby'} eq 'code') {
1517: push(@{$Sortby{$courseinfo{$course}{'code'}}},$course);
1.35 raeburn 1518: } elsif ($env{'form.sortby'} eq 'cats') {
1519: push(@{$Sortby{$courseinfo{$course}{'categories'}}},$course);
1.7 raeburn 1520: } elsif ($env{'form.sortby'} eq 'owner') {
1.22 raeburn 1521: push(@{$Sortby{$courseinfo{$course}{'ownerlastnames'}}},$course);
1.7 raeburn 1522: } else {
1.25 raeburn 1523: my $clean_title = $courseinfo{$course}{'title'};
1524: $clean_title =~ s/\W+//g;
1525: if ($clean_title eq '') {
1526: $clean_title = $courseinfo{$course}{'title'};
1527: }
1528: push(@{$Sortby{$clean_title}},$course);
1.7 raeburn 1529: }
1530: }
1531: my @sorted_courses;
1.35 raeburn 1532: if (($env{'form.sortby'} eq 'code') || ($env{'form.sortby'} eq 'owner') ||
1533: ($env{'form.sortby'} eq 'cats')) {
1.7 raeburn 1534: @sorted_courses = sort(keys(%Sortby));
1.6 raeburn 1535: } else {
1.7 raeburn 1536: @sorted_courses = sort { lc($a) cmp lc($b) } (keys(%Sortby));
1.1 raeburn 1537: }
1.24 raeburn 1538: my $count = 1;
1.72 raeburn 1539: my $totalsec = 0;
1.105 raeburn 1540: my %clutteredxlists;
1541: foreach my $course (keys(%courseinfo)) {
1542: if (ref($courseinfo{$course}) eq 'HASH') {
1543: if ($courseinfo{$course}{'xlist'} ne '') {
1544: my $crskey = $courseinfo{$course}{'cnum'}.':'.$courseinfo{$course}{'code'};
1545: my @xlists = split(/,\s/,$courseinfo{$course}{'xlist'});
1546: $clutteredxlists{$crskey} = \@xlists;
1547: }
1548: }
1549: }
1550: if (keys(%clutteredxlists)) {
1551: my %reformattedxlists = &Apache::lonnet::auto_instsec_reformat($domain,'declutter',\%clutteredxlists);
1552: foreach my $crskey (keys(%reformattedxlists)) {
1553: if (ref($reformattedxlists{$crskey}) eq 'ARRAY') {
1554: my $course = $domain.'_'.(split(/:/,$crskey))[0];
1555: $courseinfo{$course}{'xlist'} = join(', ',@{$reformattedxlists{$crskey}});
1556: }
1557: }
1558: }
1.7 raeburn 1559: foreach my $item (@sorted_courses) {
1560: foreach my $course (@{$Sortby{$item}}) {
1561: $output.=&Apache::loncommon::start_data_table_row();
1.35 raeburn 1562: $output.=&courseinfo_row($courseinfo{$course},$knownuser,$details,
1.103 raeburn 1563: \$count,$now,$course,$trails,$allitems,
1564: \%numbers,$canviewall,$hostname);
1.7 raeburn 1565: $output.=&Apache::loncommon::end_data_table_row();
1566: }
1.1 raeburn 1567: }
1.86 raeburn 1568: if (($knownuser || $canviewall) && ($count > 1) && $env{'form.showdetails'}) {
1569: if (&user_is_dc($domain) || $canviewall) {
1.72 raeburn 1570: my %lt = &Apache::lonlocal::texthash (
1571: 'Active' => 'Total current students',
1572: 'Future' => 'Total future students',
1573: 'Previous' => 'Total previous students',
1574: 'courses' => 'Total unique codes and courses without codes',
1575: 'sections' => 'Total sections',
1.73 raeburn 1576: 'xlists' => 'Total cross-listings',
1.72 raeburn 1577: );
1.73 raeburn 1578: if ($showcredits) {
1579: $lt{'cr_Active'} = &mt('Total current student credit hours');
1580: $lt{'cr_Future'} = &mt('Total future student credit hours');
1581: $lt{'cr_Previous'} = &mt('Total previous student credit hours');
1582: }
1.72 raeburn 1583: if ($env{'form.currcat_0'} eq 'communities::0') {
1584: $lt{'courses'} = &mt('Total communities');
1585: $lt{'Active'} = &mt('Total current members');
1586: $lt{'Future'} = &mt('Total future members');
1587: $lt{'Previous'} = &mt('Total previous members');
1.89 raeburn 1588: } elsif ($env{'form.currcat_0'} eq 'placement::0') {
1589: $lt{'courses'} = &mt('Total placement tests');
1.73 raeburn 1590: }
1591: my $colspan = 8;
1592: if ($showcredits) {
1593: $colspan = 4;
1594: }
1.72 raeburn 1595: $output .= '<tr class="LC_footer_row">'.
1596: '<td colspan="2"> </td>'.
1.73 raeburn 1597: '<td colspan="'.$colspan.'">'.
1.72 raeburn 1598: '<table border="0">';
1599: foreach my $item ('courses','sections','xlists') {
1600: $output .= '<tr>'.
1.73 raeburn 1601: '<td>'.$lt{$item}.'</td><td> </td>'.
1.72 raeburn 1602: '<td align="right">'.$numbers{$item}.'</td>'.
1603: '</tr>'."\n";
1604: }
1605: if (@fields > 0) {
1606: foreach my $status (@fields) {
1607: $output .= '<tr>'.
1.73 raeburn 1608: '<td>'.$lt{$status}.'</td><td> </td>'.
1.72 raeburn 1609: '<td align="right">'.$numbers{$status}.'</td>'.
1610: '</tr>'."\n";
1611: }
1612: }
1.73 raeburn 1613: $output .= '</table></td>';
1614: if ($showcredits) {
1615: $output .= '<td colspan="'.$colspan.'" valign="bottom"><table>';
1616: foreach my $status (@fields) {
1617: $output .= '<tr>'.
1618: '<td>'.$lt{'cr_'.$status}.'</td><td> </td>'.
1619: '<td align="right">'.$creditsum{$status}.'</td></tr>';
1620: }
1621: $output .= '</table></td></tr>';
1622: }
1.72 raeburn 1623: }
1624: }
1.7 raeburn 1625: $output .= &Apache::loncommon::end_data_table();
1626: return $output;
1627: }
1628:
1629: sub build_courseinfo_hash {
1.86 raeburn 1630: my ($courses,$knownuser,$domain,$canviewall,$details,$usersections,$fields,$fieldtitles,
1.73 raeburn 1631: $wasactiveon,$numbers,$creditsum,$showcredits,$defofficial,$defunofficial) = @_;
1.1 raeburn 1632: my %courseinfo;
1.7 raeburn 1633: my $now = time;
1.72 raeburn 1634: my $gettotals;
1.86 raeburn 1635: if ((keys(%{$courses}) > 0) && (&user_is_dc($domain) || $canviewall) && ($details)) {
1.72 raeburn 1636: $gettotals = 1;
1637: }
1.73 raeburn 1638: my (%uniquecodes,$nocodes,$defcreds);
1.15 raeburn 1639: foreach my $course (keys(%{$courses})) {
1.1 raeburn 1640: my $descr;
1.22 raeburn 1641: if (ref($courses->{$course}) eq 'HASH') {
1642: $descr = $courses->{$course}{'description'};
1.1 raeburn 1643: }
1644: my $cleandesc=&HTML::Entities::encode($descr,'<>&"');
1645: $cleandesc=~s/'/\\'/g;
1.10 raeburn 1646: $cleandesc =~ s/^\s+//;
1.1 raeburn 1647: my ($cdom,$cnum)=split(/\_/,$course);
1.91 raeburn 1648: my ($instcode,$singleowner,$ttype,$selfenroll_types,$extsyllplain,
1.35 raeburn 1649: $selfenroll_start,$selfenroll_end,@owners,%ownernames,$categories);
1.22 raeburn 1650: if (ref($courses->{$course}) eq 'HASH') {
1651: $descr = $courses->{$course}{'description'};
1.23 raeburn 1652: $instcode = $courses->{$course}{'inst_code'};
1.22 raeburn 1653: $singleowner = $courses->{$course}{'owner'};
1654: $ttype = $courses->{$course}{'type'};
1.27 raeburn 1655: $selfenroll_types = $courses->{$course}{'selfenroll_types'};
1656: $selfenroll_start = $courses->{$course}{'selfenroll_start_date'};
1657: $selfenroll_end = $courses->{$course}{'selfenroll_end_date'};
1.35 raeburn 1658: $categories = $courses->{$course}{'categories'};
1.91 raeburn 1659: $extsyllplain = $courses->{$course}{'extsyllplain'};
1.22 raeburn 1660: push(@owners,$singleowner);
1.67 raeburn 1661: if ($courses->{$course}{'co-owners'} ne '') {
1662: foreach my $item (split(/,/,$courses->{$course}{'co-owners'})) {
1.22 raeburn 1663: push(@owners,$item);
1664: }
1665: }
1666: }
1.72 raeburn 1667: if ($instcode ne '') {
1668: $uniquecodes{$instcode} = 1;
1669: } else {
1670: $nocodes ++;
1671: }
1.22 raeburn 1672: foreach my $owner (@owners) {
1.54 raeburn 1673: my ($ownername,$ownerdom);
1.22 raeburn 1674: if ($owner =~ /:/) {
1675: ($ownername,$ownerdom) = split(/:/,$owner);
1676: } else {
1677: $ownername = $owner;
1678: if ($owner ne '') {
1679: $ownerdom = $cdom;
1680: }
1681: }
1682: if ($ownername ne '' && $ownerdom ne '') {
1683: my %namehash=&Apache::loncommon::getnames($ownername,$ownerdom);
1684: $ownernames{$ownername.':'.$ownerdom} = \%namehash;
1.1 raeburn 1685: }
1686: }
1687: $courseinfo{$course}{'cdom'} = $cdom;
1688: $courseinfo{$course}{'cnum'} = $cnum;
1689: $courseinfo{$course}{'code'} = $instcode;
1.22 raeburn 1690: my @lastnames;
1691: foreach my $owner (keys(%ownernames)) {
1692: if (ref($ownernames{$owner}) eq 'HASH') {
1693: push(@lastnames,$ownernames{$owner}{'lastname'});
1694: }
1695: }
1696: $courseinfo{$course}{'ownerlastnames'} = join(', ',sort(@lastnames));
1.1 raeburn 1697: $courseinfo{$course}{'title'} = $cleandesc;
1.22 raeburn 1698: $courseinfo{$course}{'owner'} = $singleowner;
1.27 raeburn 1699: $courseinfo{$course}{'selfenroll_types'} = $selfenroll_types;
1700: $courseinfo{$course}{'selfenroll_start'} = $selfenroll_start;
1701: $courseinfo{$course}{'selfenroll_end'} = $selfenroll_end;
1.35 raeburn 1702: $courseinfo{$course}{'categories'} = $categories;
1.91 raeburn 1703: $courseinfo{$course}{'extsyllplain'} = $extsyllplain;
1.7 raeburn 1704:
1705: my %coursehash = &Apache::lonnet::dump('environment',$cdom,$cnum);
1706: my @classids;
1707: my @crosslistings;
1.15 raeburn 1708: my ($seclist,$numsec) =
1709: &identify_sections($coursehash{'internal.sectionnums'});
1.7 raeburn 1710: $courseinfo{$course}{'seclist'} = $seclist;
1.15 raeburn 1711: my ($xlist_items,$numxlist) =
1712: &identify_sections($coursehash{'internal.crosslistings'});
1.72 raeburn 1713: if (ref($numbers) eq 'HASH') {
1714: $numbers->{'sections'} += $numsec;
1715: $numbers->{'xlists'} += $numxlist;
1716: }
1.7 raeburn 1717: my $showsyllabus = 1; # default is to include a syllabus link
1718: if (defined($coursehash{'showsyllabus'})) {
1719: $showsyllabus = $coursehash{'showsyllabus'};
1720: }
1721: $courseinfo{$course}{'showsyllabus'} = $showsyllabus;
1.73 raeburn 1722: if ($showcredits) {
1723: if ($coursehash{'internal.defaultcredits'}) {
1724: $courseinfo{$course}{'defaultcredits'} = $coursehash{'internal.defaultcredits'};
1725: } elsif ($instcode ne '') {
1726: $courseinfo{$course}{'defaultcredits'} = $defofficial;
1727: } else {
1728: $courseinfo{$course}{'defaultcredits'} = $defunofficial;
1729: }
1730: $defcreds = $courseinfo{$course}{'defaultcredits'};
1731: }
1.15 raeburn 1732: if (((defined($env{'form.coursenum'}) && ($cnum eq $env{'form.coursenum'}))) ||
1.86 raeburn 1733: (($knownuser || $canviewall) && ($details == 1))) {
1.72 raeburn 1734: my $milestone;
1735: if ($wasactiveon eq 'accessend') {
1736: if ($coursehash{'default_enrollment_end_date'}) {
1737: $milestone = $coursehash{'default_enrollment_end_date'};
1738: } else {
1739: $milestone = time;
1740: }
1741: } elsif ($wasactiveon eq 'enrollend') {
1742: if ($coursehash{'internal.autoend'}) {
1743: $milestone = $coursehash{'internal.autoend'};
1744: } else {
1745: $milestone = time;
1746: }
1747: } else {
1748: $milestone = $wasactiveon;
1749: }
1750: $courseinfo{$course}{'counts'} =
1751: &count_students($cdom,$cnum,$numsec,$fields,$fieldtitles,$gettotals,
1.73 raeburn 1752: $numbers,$creditsum,$showcredits,$defcreds,$milestone);
1.72 raeburn 1753: if ($instcode ne '') {
1754: $courseinfo{$course}{'autoenrollment'} =
1755: &autoenroll_info(\%coursehash,$now,$seclist,$xlist_items,
1756: $instcode,\@owners,$cdom,$cnum);
1757: }
1.15 raeburn 1758: my $startaccess = '';
1759: my $endaccess = '';
1760: my $accessdates;
1761: if ( defined($coursehash{'default_enrollment_start_date'}) ) {
1762: $startaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_start_date'});
1763: }
1764: if ( defined($coursehash{'default_enrollment_end_date'}) ) {
1765: $endaccess = &Apache::lonlocal::locallocaltime($coursehash{'default_enrollment_end_date'});
1766: if ($coursehash{'default_enrollment_end_date'} == 0) {
1.34 raeburn 1767: $endaccess = &mt('No ending date');
1.15 raeburn 1768: }
1769: }
1770: if ($startaccess) {
1.42 bisitz 1771: $accessdates .= '<i>'.&mt('From:[_1]','</i> '.$startaccess).'<br />';
1.7 raeburn 1772: }
1.15 raeburn 1773: if ($endaccess) {
1.42 bisitz 1774: $accessdates .= '<i>'.&mt('To:[_1]','</i> '.$endaccess).'<br />';
1.15 raeburn 1775: }
1.34 raeburn 1776: if (($selfenroll_types ne '') &&
1777: ($selfenroll_end > 0 && $selfenroll_end > $now)) {
1778: my ($selfenroll_start_access,$selfenroll_end_access);
1779: if (($coursehash{'default_enrollment_start_date'} ne
1780: $coursehash{'internal.selfenroll_start_access'}) ||
1781: ($coursehash{'default_enrollment_end_date'} ne
1782: $coursehash{'internal.selfenroll_end_access'})) {
1783: if ( defined($coursehash{'internal.selfenroll_start_access'}) ) {
1784: $selfenroll_start_access = &Apache::lonlocal::locallocaltime($coursehash{'internal.selfenroll_start_access'});
1785: }
1786: if ( defined($coursehash{'default_enrollment_end_date'}) ) {
1787: $selfenroll_end_access = &Apache::lonlocal::locallocaltime($coursehash{'internal.selfenroll_end_access'});
1788: if ($coursehash{'internal.selfenroll_end_access'} == 0) {
1789: $selfenroll_end_access = &mt('No ending date');
1790: }
1791: }
1792: if ($selfenroll_start_access || $selfenroll_end_access) {
1793: $accessdates .= '<br/><br /><i>'.&mt('Self-enrollers:').'</i><br />';
1794: if ($selfenroll_start_access) {
1.42 bisitz 1795: $accessdates .= '<i>'.&mt('From:[_1]','</i> '.$selfenroll_start_access).'<br />';
1.34 raeburn 1796: }
1797: if ($selfenroll_end_access) {
1.42 bisitz 1798: $accessdates .= '<i>'.&mt('To:[_1]','</i> '.$selfenroll_end_access).'<br />';
1.34 raeburn 1799: }
1800: }
1801: }
1802: }
1.15 raeburn 1803: $courseinfo{$course}{'access'} = $accessdates;
1.1 raeburn 1804: }
1.7 raeburn 1805: if ($xlist_items eq '') {
1806: $xlist_items = &mt('No');
1.1 raeburn 1807: }
1.7 raeburn 1808: $courseinfo{$course}{'xlist'} = $xlist_items;
1.1 raeburn 1809: }
1.72 raeburn 1810: if (ref($numbers) eq 'HASH') {
1811: $numbers->{'courses'} = $nocodes + scalar(keys(%uniquecodes));
1812: }
1.7 raeburn 1813: return %courseinfo;
1.1 raeburn 1814: }
1815:
1.7 raeburn 1816: sub count_students {
1.73 raeburn 1817: my ($cdom,$cnum,$numsec,$fieldsref,$titlesref,$getcounts,$numbers,$creditsum,
1818: $showcredits,$defcreds,$wasactiveon) = @_;
1.72 raeburn 1819: my $countslist = '<span class="LC_nobreak">'.
1820: &mt('[quant,_1,section,sections,No sections]',$numsec).'</span>';
1821: my (@fields,%titles,$showexpired);
1822: if ((ref($fieldsref) eq 'ARRAY') && (ref($titlesref) eq 'HASH') &&
1823: (ref($numbers) eq 'HASH')) {
1824: @fields = @{$fieldsref};
1825: %titles = %{$titlesref};
1826: if (grep(/^Previous$/,@fields)) {
1827: $showexpired = 1;
1828: }
1829: } else {
1830: return;
1831: }
1.1 raeburn 1832: my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cnum);
1.73 raeburn 1833: my (%student_count,%credit_count);
1834: %student_count = (
1.72 raeburn 1835: Active => 0,
1836: Future => 0,
1837: Previous => 0,
1.73 raeburn 1838: );
1839: if ($showcredits) {
1840: %credit_count = (
1841: Active => 0,
1842: Future => 0,
1843: Previous => 0,
1844: );
1845: }
1.1 raeburn 1846: my %idx;
1847: $idx{'status'} = &Apache::loncoursedata::CL_STATUS();
1.72 raeburn 1848: $idx{'end'} = &Apache::loncoursedata::CL_END();
1.73 raeburn 1849: $idx{'credits'} = &Apache::loncoursedata::CL_CREDITS();
1.4 albertel 1850: while (my ($student,$data) = each(%$classlist)) {
1.72 raeburn 1851: my $status = $data->[$idx{'status'}];
1.73 raeburn 1852: my $credits = $data->[$idx{'credits'}];
1853: if ($credits eq '') {
1854: $credits = $defcreds;
1855: }
1.72 raeburn 1856: if ($status eq 'Expired') {
1857: if (($showexpired) &&
1858: ($data->[$idx{'end'}] >= $wasactiveon)) {
1859: $student_count{'Previous'} ++;
1.73 raeburn 1860: if ($showcredits) {
1861: $credit_count{'Previous'} += $credits;
1862: }
1.72 raeburn 1863: }
1864: } else {
1865: $student_count{$status} ++;
1.73 raeburn 1866: if ($showcredits) {
1867: $credit_count{$status} += $credits;
1868: }
1.72 raeburn 1869: }
1.1 raeburn 1870: }
1.72 raeburn 1871: if (@fields) {
1872: $countslist .= ':<br />';
1873: foreach my $status (@fields) {
1874: $countslist .= '<span class="LC_nobreak">'.$titles{$status}.': '.
1875: $student_count{$status}.'</span><br />';
1876: $numbers->{$status} += $student_count{$status};
1.73 raeburn 1877: if ($showcredits) {
1878: $creditsum->{$status} += $credit_count{$status};
1879: }
1.72 raeburn 1880: }
1.1 raeburn 1881: }
1.7 raeburn 1882: return $countslist;
1883: }
1884:
1885: sub courseinfo_row {
1.103 raeburn 1886: my ($info,$knownuser,$details,$countref,$now,$course,$trails,$allitems,
1887: $numbers,$canviewall,$hostname) = @_;
1.7 raeburn 1888: my ($cdom,$cnum,$title,$ownerlast,$code,$owner,$seclist,$xlist_items,
1.91 raeburn 1889: $accessdates,$showsyllabus,$counts,$autoenrollment,$output,$categories,
1890: $extsyllplain);
1.7 raeburn 1891: if (ref($info) eq 'HASH') {
1892: $cdom = $info->{'cdom'};
1893: $cnum = $info->{'cnum'};
1894: $title = $info->{'title'};
1.22 raeburn 1895: $ownerlast = $info->{'ownerlastnames'};
1.7 raeburn 1896: $code = $info->{'code'};
1897: $owner = $info->{'owner'};
1898: $seclist = $info->{'seclist'};
1899: $xlist_items = $info->{'xlist'};
1900: $accessdates = $info->{'access'};
1901: $counts = $info->{'counts'};
1902: $autoenrollment = $info->{'autoenrollment'};
1903: $showsyllabus = $info->{'showsyllabus'};
1.91 raeburn 1904: $extsyllplain = $info->{'extsyllplain'};
1.35 raeburn 1905: $categories = $info->{'categories'};
1.7 raeburn 1906: } else {
1907: $output = '<td colspan="8">'.&mt('No information available for [_1].',
1908: $code).'</td>';
1909: return $output;
1.2 raeburn 1910: }
1.35 raeburn 1911: $output .= '<td>'.$$countref.'</td>';
1912: if ($env{'form.currcat_0'} eq 'instcode::0') {
1913: $output .= '<td>'.$code.'</td>';
1914: } else {
1915: my ($categorylist,@cats);
1916: if ($categories ne '') {
1917: @cats = split('&',$categories);
1918: }
1919: if ((ref($trails) eq 'ARRAY') && (ref($allitems) eq 'HASH')) {
1.107 raeburn 1920: my @categories;
1921: foreach my $cat (@cats) {
1922: next if ($cat eq '');
1923: if (($allitems->{$cat} ne '') && ($trails->[$allitems->{$cat}] ne '')) {
1924: push(@categories,$trails->[$allitems->{$cat}]);
1925: }
1926: }
1.35 raeburn 1927: $categorylist = join('<br />',@categories);
1928: }
1929: if ($categorylist eq '') {
1930: $categorylist = ' ';
1931: }
1932: $output .= '<td>'.$categorylist.'</td>';
1933: }
1934: $output .= '<td>'.$seclist.'</td>'.
1.7 raeburn 1935: '<td>'.$xlist_items.'</td>'.
1936: '<td>'.$title.' <font size="-2">';
1.2 raeburn 1937: if ($showsyllabus) {
1.91 raeburn 1938: my $usehttp = 0;
1939: if (($ENV{'SERVER_PORT'} == 443) && ($extsyllplain)) {
1.103 raeburn 1940: unless ((&Apache::lonnet::uses_sts()) ||
1.104 raeburn 1941: (&Apache::lonnet::waf_allssl($hostname))) {
1.98 raeburn 1942: $usehttp = 1;
1943: }
1.91 raeburn 1944: }
1945: $output .= '<a href="javascript:ToSyllabus('."'$cdom','$cnum','$usehttp'".')">'.&mt('Syllabus').'</a>';
1.7 raeburn 1946: } else {
1947: $output .= ' ';
1.2 raeburn 1948: }
1949: $output .= '</font></td>'.
1.7 raeburn 1950: '<td>'.$ownerlast.'</td>';
1.86 raeburn 1951: if (($knownuser) || ($canviewall && $details)) {
1.15 raeburn 1952: if ($details) {
1.72 raeburn 1953: $output .=
1954: '<td>'.$accessdates.'</td>'.
1955: '<td>'.$counts.'</td>';
1.89 raeburn 1956: unless (($env{'form.currcat_0'} eq 'communities::0') || ($env{'form.currcat_0'} eq 'placement::0')) {
1.72 raeburn 1957: $output .= '<td>'.$autoenrollment.'</td>';
1.60 raeburn 1958: }
1.15 raeburn 1959: } else {
1960: $output .= "<td><a href=\"javascript:setCourseId('$cnum')\">".&mt('Show more details').'</a></td>';
1.8 raeburn 1961: }
1.7 raeburn 1962: }
1.82 raeburn 1963: my $selfenroll = &selfenroll_status($info,$course);
1964: if ($selfenroll) {
1965: $output .= '<td>'.$selfenroll.'</td>';
1966: } else {
1967: $output .= '<td> </td>';
1968: }
1969: $$countref ++;
1970: return $output;
1971: }
1972:
1973: sub selfenroll_status {
1974: my ($info,$course) = @_;
1975: my $now = time;
1976: my $output;
1977: if (ref($info) eq 'HASH') {
1978: if ($info->{'selfenroll_types'}) {
1979: my $showstart = &Apache::lonlocal::locallocaltime($info->{'selfenroll_start'});
1980: my $showend = &Apache::lonlocal::locallocaltime($info->{'selfenroll_end'});
1981: if (($info->{'selfenroll_end'} > 0) && ($info->{'selfenroll_end'} > $now)) {
1982: if (($info->{'selfenroll_start'} > 0) && ($info->{'selfenroll_start'} > $now)) {
1983: $output = &mt('Starts: [_1]','<span class="LC_cusr_emph">'.$showstart.'</span>').'<br />'.&mt('Ends: [_1]','<span class="LC_cusr_emph">'.$showend.'</span>');
1984: } else {
1985: $output = '<a href="javascript:ToSelfenroll('."'$course'".')">'.
1986: &mt('Enroll in course').'</a><br />';
1987: if ($info->{'selfenroll_end'} == 0) {
1988: $output .= &mt('Available permanently');
1989: } elsif ($info->{'selfenroll_end'} > $now) {
1990: $output .= &mt('Self-enrollment ends: [_1]','<span class="LC_cusr_emph">'.$showend.'</span>');
1991: }
1.66 raeburn 1992: }
1.27 raeburn 1993: }
1994: }
1995: }
1.1 raeburn 1996: return $output;
1997: }
1998:
1999: sub identify_sections {
2000: my ($seclist) = @_;
2001: my @secnums;
2002: if ($seclist =~ /,/) {
1.4 albertel 2003: my @sections = split(/,/,$seclist);
1.1 raeburn 2004: foreach my $sec (@sections) {
2005: $sec =~ s/:[^:]*$//;
2006: push(@secnums,$sec);
2007: }
2008: } else {
2009: if ($seclist =~ m/^([^:]+):/) {
2010: my $sec = $1;
1.4 albertel 2011: if (!grep(/^\Q$sec\E$/,@secnums)) {
2012: push(@secnums,$sec);
1.1 raeburn 2013: }
2014: }
2015: }
2016: @secnums = sort {$a <=> $b} @secnums;
1.39 raeburn 2017: $seclist = join(', ',@secnums);
1.15 raeburn 2018: my $numsec = @secnums;
2019: return ($seclist,$numsec);
1.1 raeburn 2020: }
2021:
1.2 raeburn 2022: sub get_valid_classes {
1.22 raeburn 2023: my ($seclist,$xlist_items,$crscode,$owners,$cdom,$cnum) = @_;
1.2 raeburn 2024: my $response;
1.105 raeburn 2025: my (@sections,@format_sections,@xlists,%possclasses,%okclasses,%validations);
1.2 raeburn 2026: @{$validations{'sections'}} = ();
2027: @{$validations{'xlists'}} = ();
2028: my $totalitems = 0;
2029: if ($seclist) {
1.95 raeburn 2030: @sections = split(/,\s+/,$seclist);
1.105 raeburn 2031: my $crskey = $cnum.':'.$crscode;
2032: my %formattedsec = &Apache::lonnet::auto_instsec_reformat($cdom,'clutter',
2033: {$crskey => \@sections});
2034: if (ref($formattedsec{$crskey}) eq 'ARRAY') {
2035: @format_sections = @{$formattedsec{$crskey}};
2036: map { $possclasses{$crscode.$_} = 1; } @format_sections;
2037: }
1.95 raeburn 2038: }
2039: if ($xlist_items) {
2040: @xlists = split(/,\s+/,$xlist_items);
2041: map { $possclasses{$_} = 1; } @xlists;
2042: }
2043: my %okclasses = &Apache::lonnet::auto_validate_instclasses($cdom,$cnum,$owners,
2044: \%possclasses);
2045: if (keys(%okclasses)) {
1.105 raeburn 2046: for (my $i=0; $i<@sections; $i++) {
2047: if ($okclasses{$crscode.$format_sections[$i]}) {
2048: my $sec = $sections[$i];
2049: if (!grep(/^\Q$sec\E$/,@{$validations{'sections'}})) {
1.4 albertel 2050: push(@{$validations{'sections'}},$sec);
1.2 raeburn 2051: $totalitems ++;
2052: }
2053: }
2054: }
1.95 raeburn 2055: foreach my $item (@xlists) {
2056: if ($okclasses{$item}) {
2057: if (!grep(/^\Q$item\E$/,@{$validations{'xlists'}})) {
1.4 albertel 2058: push(@{$validations{'xlists'}},$item);
1.2 raeburn 2059: $totalitems ++;
2060: }
2061: }
2062: }
2063: }
2064: if ($totalitems > 0) {
2065: if (@{$validations{'sections'}}) {
1.42 bisitz 2066: $response = &mt('Sections:').' '.
1.14 raeburn 2067: join(', ',@{$validations{'sections'}}).'<br />';
1.2 raeburn 2068: }
2069: if (@{$validations{'xlists'}}) {
1.105 raeburn 2070: my $crskey = $cnum.':'.$crscode;
2071: my %reformattedxlists =
2072: &Apache::lonnet::auto_instsec_reformat($cdom,'declutter',
2073: {$crskey => $validations{'xlists'}});
2074: if (ref($reformattedxlists{$crskey}) eq 'ARRAY') {
2075: $validations{'xlists'} = $reformattedxlists{$crskey};
2076: }
1.42 bisitz 2077: $response .= &mt('Courses:').' '.
1.14 raeburn 2078: join(', ',@{$validations{'xlists'}});
1.2 raeburn 2079: }
2080: }
2081: return $response;
2082: }
2083:
1.7 raeburn 2084: sub autoenroll_info {
1.22 raeburn 2085: my ($coursehash,$now,$seclist,$xlist_items,$code,$owners,$cdom,$cnum) = @_;
1.7 raeburn 2086: my $autoenrolldates = &mt('Not enabled');
2087: if (defined($coursehash->{'internal.autoadds'}) && $coursehash->{'internal.autoadds'} == 1) {
2088: my ($autostart,$autoend);
2089: if ( defined($coursehash->{'internal.autostart'}) ) {
2090: $autostart = &Apache::lonlocal::locallocaltime($coursehash->{'internal.autostart'});
2091: }
2092: if ( defined($coursehash->{'internal.autoend'}) ) {
2093: $autoend = &Apache::lonlocal::locallocaltime($coursehash->{'internal.autoend'});
2094: }
2095: if ($coursehash->{'internal.autostart'} > $now) {
2096: if ($coursehash->{'internal.autoend'} && $coursehash->{'internal.autoend'} < $now) {
2097: $autoenrolldates = &mt('Not enabled');
2098: } else {
2099: my $valid_classes =
2100: &get_valid_classes($seclist,$xlist_items,$code,
1.22 raeburn 2101: $owners,$cdom,$cnum);
1.7 raeburn 2102: if ($valid_classes ne '') {
1.42 bisitz 2103: $autoenrolldates = &mt('Not enabled').'<br />'
2104: .&mt('Starts: [_1]',$autostart)
2105: .'<br />'.$valid_classes;
2106: }
1.7 raeburn 2107: }
2108: } else {
2109: if ($coursehash->{'internal.autoend'} && $coursehash->{'internal.autoend'} < $now) {
1.42 bisitz 2110: $autoenrolldates = &mt('Not enabled').'<br />'
2111: .&mt('Ended: [_1]',$autoend);
1.7 raeburn 2112: } else {
2113: my $valid_classes = &get_valid_classes($seclist,$xlist_items,
1.22 raeburn 2114: $code,$owners,$cdom,$cnum);
1.7 raeburn 2115: if ($valid_classes ne '') {
1.42 bisitz 2116: $autoenrolldates = &mt('Currently enabled').'<br />'.
1.7 raeburn 2117: $valid_classes;
2118: }
2119: }
2120: }
2121: }
2122: return $autoenrolldates;
2123: }
2124:
1.8 raeburn 2125: sub user_is_known {
2126: my $known = 0;
2127: if ($env{'user.name'} ne '' && $env{'user.name'} ne 'public'
2128: && $env{'user.domain'} ne '' && $env{'user.domain'} ne 'public') {
2129: $known = 1;
2130: }
2131: return $known;
2132: }
2133:
1.1 raeburn 2134: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>