--- loncom/interface/courseclassifier.pm 2007/10/06 04:32:49 1.3 +++ loncom/interface/courseclassifier.pm 2013/07/15 14:32:45 1.15 @@ -1,3 +1,7 @@ +# The LearningOnline Network with CAPA +# Utilities for classifying courses based on institutional code +# +# $Id: courseclassifier.pm,v 1.15 2013/07/15 14:32:45 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -26,6 +30,8 @@ package Apache::courseclassifier; use strict; use lib '/home/httpd/lib/perl/'; use Apache::lonnet; +use Apache::loncommon; +use Apache::lonlocal; use LONCAPA; sub retrieve_instcodes { @@ -34,8 +40,10 @@ sub retrieve_instcodes { my %courses = &Apache::lonnet::courseiddump($codedom,'.',1,'.','.','.', undef,undef,'Course'); foreach my $course (keys(%courses)) { if (ref($courses{$course}) eq 'HASH') { - $$coursecodes{$course} = $courses{$course}{'inst_code'}; - $totcodes ++; + if ($courses{$course}{'inst_code'} ne '') { + $$coursecodes{$course} = $courses{$course}{'inst_code'}; + $totcodes ++; + } } } return $totcodes; @@ -47,7 +55,7 @@ sub sort_cats { if (defined($$cat_order{$$codetitles[$num]})) { foreach my $item (@{$$cat_order{$$codetitles[$num]}}) { if (grep/^\Q$item\E$/,@unsorted) { - push @{$sorted}, $item; + push(@{$sorted},$item); } } } else { @@ -117,7 +125,8 @@ sub recurse_list { } } else { %{$$idarrays{$$codetitles[4]}{$$codes{$cid}{$$codetitles[0]}}{$$codes{$cid}{$$codetitles[1]}}} = (); - %{$$idarrays{$$codetitles[4]}{$$codes{$cid}{$$codetitles[0]}}{$$codes{$cid}{$$codetitles[1]}}{$$codes{$cid}{$$codetitles[2]}}} = (); @{$$idarrays{$$codetitles[4]}{$$codes{$cid}{$$codetitles[0]}}{$$codes{$cid}{$$codetitles[1]}}{$$codes{$cid}{$$codetitles[2]}}{$$codes{$cid}{$$codetitles[3]}}} = ("$$codes{$cid}{$$codetitles[4]}"); + %{$$idarrays{$$codetitles[4]}{$$codes{$cid}{$$codetitles[0]}}{$$codes{$cid}{$$codetitles[1]}}{$$codes{$cid}{$$codetitles[2]}}} = (); + @{$$idarrays{$$codetitles[4]}{$$codes{$cid}{$$codetitles[0]}}{$$codes{$cid}{$$codetitles[1]}}{$$codes{$cid}{$$codetitles[2]}}{$$codes{$cid}{$$codetitles[3]}}} = ("$$codes{$cid}{$$codetitles[4]}"); } } else { %{$$idarrays{$$codetitles[4]}{$$codes{$cid}{$$codetitles[0]}}} = (); @@ -214,7 +223,7 @@ sub build_code_selections { $$idlist{$$codetitles[3]}{$key_a}{$key_b}{$key_c} = join('","',@sorted_c); $$idnums{$$codetitles[3]}{$key_a}{$key_b}{$key_c} = scalar(@sorted_c); if (defined($$cat_titles{$$codetitles[3]})) { - $$idlist_titles{$$codetitles[2]}{$key_a}{$key_b} = join('","',@sorted_c_titles); + $$idlist_titles{$$codetitles[3]}{$key_a}{$key_b}{$key_c} = join('","',@sorted_c_titles); } } } @@ -238,6 +247,9 @@ sub build_code_selections { } $$idlist{$$codetitles[4]}{$key_a}{$key_b}{$key_c}{$key_d} = join('","',@sorted_d); $$idnums{$$codetitles[4]}{$key_a}{$key_b}{$key_c}{$key_d} = scalar(@sorted_d); + if (defined($$cat_titles{$$codetitles[4]})) { + $$idlist_titles{$$codetitles[3]}{$key_a}{$key_b}{$key_c}{$key_d} = join('","',@sorted_d_titles); + } } } } @@ -249,12 +261,16 @@ sub build_code_selections { sub javascript_code_selections { my ($formname,@codetitles) = @_; my $numtitles = @codetitles; + my %lt = &Apache::lonlocal::texthash( + Select => 'Select', + Pick => 'Pick', + ); my $output = (< 0) { + if (&Apache::lonnet::auto_instcode_format($caller,$codedom,\%coursecodes, + \%codes,$codetitles,$cat_titles,$cat_order) eq 'ok') { + &build_code_selections(\%codes,$codetitles,$cat_titles,$cat_order, + \%idlist,\%idnums,\%idlist_titles); + my ($scripttext,$longtitles) = + &javascript_definitions($codetitles,\%idlist,\%idlist_titles, + \%idnums,$cat_titles); + my $longtitles_str = join('","',@{$longtitles}); + my $allidlist = $idlist{$codetitles->[0]}; + $numtitles = @{$codetitles}; + $lasttitle = $numtitles; + if ($numtitles > 4) { + $lasttitle = 4; + } + if ($numtitles == 0) { + if (!defined($env{'form.state'})) { + $env{'form.state'} = 'listing'; + } + } else { + my @data = ('top'); + for (my $k=0; $k<$lasttitle; $k++) { + my $cat = $codetitles->[$k]; + my $level = 1; + $level = &recurse_options($codetitles->[$k],$idlist{$codetitles->[$k]},$level,$cat,$cat_items,\@data,\%by_year,\%by_sem,\%by_dept); + } + $scripttext .= &build_javascript(\%by_year,\%by_sem,\%by_dept,$cat_order,$codetitles); + if ($officialjs) { + $jscript .= ' + +function toggleOfficial() {'; + for (my $i=0; $i<@{$codetitles}-1; $i++) { + $jscript .= ' + document.'.$formname.'.'.$codetitles->[$i].'.selectedIndex = 0;'; + } + $jscript .= ' +} + +function setOfficial(caller) { + if (typeof(caller) != "undefined") { + if (caller.options[caller.selectedIndex].value != 0) { + if (document.'.$formname.'.official.length > 0) { + for (var j=0; j[$i]} = $standardnames[$i]; + } + } + $jscript .= ' +function setElements() { +'; + for (my $i=0; $i<@{$codetitles}-1; $i++) { + my $item = $local_to_standard{$codetitles->[$i]}; + if ($env{'form.'.$item} != -1) { + $jscript .= ' + for (var j=0; j[-1]}; + if ($env{'form.'.$lastcodetitle} != -1) { + $jscript .= ' + for (var j=0; j 0) { + $output .= ''; + for (my $k=0; $k<$lasttitle-1; $k++) { + my (@items,@unsorted); + if (ref($cat_items->{$codetitles->[$k]}) eq 'ARRAY') { + @unsorted = @{$cat_items->{$codetitles->[$k]}}; + } + &sort_cats($k,$cat_order,$codetitles,\@unsorted,\@items); + my @longitems; + if (defined($cat_titles->{$codetitles->[$k]})) { + foreach my $item (@items) { + push(@longitems,$cat_titles->{$codetitles->[$k]}{$item}); + } + } else { + @longitems = @items; + } + $output .= ''; + } + $output .= '
'.$codetitles->[$k].'
'."\n". + '
'.$codetitles->[$lasttitle-1].'
'."\n". + ''."\n". + '
'."\n"; + if ($numtitles > 4) { + $output .= '

'.$codetitles->[$numtitles-1].'
'."\n". + '
'."\n"; + } + $output .= '
'; + } + return $output; +} + +sub recurse_options { + my ($currkey,$currlist,$level,$cat,$cat_options,$data,$by_year,$by_sem,$by_dept) = @_; + if (ref($currlist) eq 'HASH') { + $level ++; + foreach my $key (sort(keys(%{$currlist}))) { + $$data[$level-1]= $key; + &recurse_options($key,$currlist->{$key},$level,$cat,$cat_options,$data,$by_year,$by_sem,$by_dept); + } + } else { + $level --; + my @contents = split(/","/,$currlist); + foreach my $item (@contents) { + if (!grep(/^\Q$item\E$/,@{$cat_options->{$cat}})) { + push(@{$cat_options->{$cat}},$item); + } + if ($level == 3) { + if (!grep/^\Q$item\E$/,@{$by_year->{$data->[1]}->{$currkey}}) { + push(@{$by_year->{$data->[1]}->{$currkey}},$item); + } + if (!grep/^\Q$item\E$/,@{$by_sem->{$data->[2]}->{$currkey}}) { + push(@{$by_sem->{$data->[2]}->{$currkey}},$item); + } + if (!grep/^\Q$item\E$/,@{$by_dept->{$currkey}}) { + push(@{$by_dept->{$currkey}},$item); + } + + } + } + } + return $level; +} + +sub build_javascript { + my ($by_year,$by_sem,$by_dept,$cat_order,$codetitles) = @_; + my @unsorted = keys(%{$by_year}); + my @sorted_yrs; + &sort_cats('0',$cat_order,$codetitles,\@unsorted,\@sorted_yrs); my $output = 'var idcse_by_yr_year = new Array("'.join('","',@sorted_yrs).'");'."\n". + 'var idcse_by_yr_dept = new Array('.scalar(@sorted_yrs).');'."\n". + 'var idcse_by_yr_num = new Array('.scalar(@sorted_yrs).');'."\n"; + for (my $i=0; $i<@sorted_yrs; $i++) { + my $numkeys = keys(%{$by_year->{$sorted_yrs[$i]}}); + $output .= " idcse_by_yr_num[$i] = new Array($numkeys);\n"; + if (ref($by_year->{$sorted_yrs[$i]}) eq 'HASH') { + @unsorted = keys(%{$by_year->{$sorted_yrs[$i]}}); + my @sorted_depts; + &Apache::courseclassifier::sort_cats('2',$cat_order,$codetitles,\@unsorted,\@sorted_depts); + $output .= qq| idcse_by_yr_dept[$i] = new Array ("|.join('","',@sorted_depts).'");'."\n"; + for (my $j=0; $j<@sorted_depts; $j++) { + $output .= qq| idcse_by_yr_num[$i][$j] = new Array ("|; + $output .= join('","',sort(@{$by_year->{$sorted_yrs[$i]}->{$sorted_depts[$j]}})).'");'."\n"; + } + } + } + @unsorted = keys(%{$by_sem}); + my @sorted_sems; + &sort_cats('1',$cat_order,$codetitles,\@unsorted,\@sorted_sems); + $output .= 'idcse_by_sem_sems = new Array("'.join('","',@sorted_sems).'");'."\n". + 'idcse_by_sem_dept = new Array('.scalar(@sorted_sems).');'."\n". + 'idcse_by_sem_num = new Array('.scalar(@sorted_sems).');'."\n"; + for (my $i=0; $i<@sorted_sems; $i++) { + my $numkeys = keys(%{$by_sem->{$sorted_sems[$i]}}); + $output .= " idcse_by_sem_num[$i] = new Array($numkeys);\n"; + if (ref($by_sem->{$sorted_sems[$i]}) eq 'HASH') { + @unsorted = keys(%{$by_sem->{$sorted_sems[$i]}}); + my @sorted_depts; + &sort_cats('2',$cat_order,$codetitles,\@unsorted,\@sorted_depts); + $output .= qq| idcse_by_sem_dept[$i] = new Array("|.join('","',@sorted_depts).'");'."\n"; + for (my $j=0; $j<@sorted_depts; $j++) { + $output .= qq| idcse_by_sem_num[$i][$j] = new Array ("|.join('","',sort(@{$by_sem->{$sorted_sems[$i]}->{$sorted_depts[$j]}})).'");'."\n"; + } + } + } + @unsorted = keys(%{$by_dept}); + my @sorted_deps; + &sort_cats('2',$cat_order,$codetitles,\@unsorted,\@sorted_deps); + $output .= 'idcse_by_dep = new Array('.scalar(@sorted_deps).');'."\n"; + for (my $k=0; $k<@sorted_deps; $k++) { + $output .= qq| idcse_by_dep[$k] = new Array ("|.join('","',sort(@{$by_dept->{$sorted_deps[$k]}})).'");'."\n"; + } + return $output; +} + +sub javascript_select_filler { + my ($formname,$scripttext,$codetitles,$longtitles_str,$allidlist,$officialjs) = @_; + my $all = &mt('All'); + my $nocrs = &mt('No courses'); + my $output = < -1) { + document.$formname.Number.options[0] = new Option('$all','0',false,false); + for (var k=0; k -1) { + for (var i=0; i -1) { + for (var i=0; i -1) { + for (var k=0; k[$i]} = $standardnames[$i]; + } + } + if ($defaults_result eq 'ok') { + $instcode ='^'; + foreach my $loctitle (@code_order) { + my $item = $local_to_standard{$loctitle}; + if ($item ne '') { + if ($env{'form.'.$item} eq '0' ) { + $instcode .= $codedefaults{$loctitle}; + } else { + $instcode .= $env{'form.'.$item}; + } + } else { + $instcode .= '.+'; + } + } + $instcode .= '$'; + } else { + $instcode = '.+'; + } + } + return $instcode; +} + +sub instcode_from_selectors { + my ($cdom,$noregexps) = @_; + my $instcode; + my $caller = 'global'; + my (%coursecodes,%codes,@codetitles,%cat_titles,%cat_order, + %codedefaults,@code_order); + my $format_reply = + &Apache::lonnet::auto_instcode_format($caller,$cdom,\%coursecodes, + \%codes,\@codetitles,\%cat_titles,\%cat_order); + my $defaults_result = + &Apache::lonnet::auto_instcode_defaults($cdom,\%codedefaults, + \@code_order); + if (($defaults_result eq 'ok') && ($format_reply eq 'ok')) { + my @standardnames = &Apache::loncommon::get_standard_codeitems(); + my %local_to_standard; + for (my $i=0; $i<@codetitles; $i++) { + $local_to_standard{$codetitles[$i]} = $standardnames[$i]; + } + foreach my $loctitle (@code_order) { + my $category = $local_to_standard{$loctitle}; + if ($category ne '') { + if ($env{'form.'.$category} eq '-1' ) { + if ($noregexps) { + $instcode .= ' '; + } else { + $instcode .= $codedefaults{$category}; + } + } else { + $instcode .= $env{'form.'.$category}; + } + } else { + $instcode .= '.+'; + } + } + } + return $instcode; +} + 1;