'.$display.' ');
+ $r->print(&start_data_table_row().''.$display.' ');
$r->print('');
@@ -7233,7 +7953,7 @@ sub csv_print_select_table {
foreach my $sample (sort({$a <=> $b} keys(%{ $samples->[0] }))) {
$r->print('Column '.($sample+1).' ');
+ '>'.&mt('Column [_1]',($sample+1)).'');
}
$r->print(' '.&end_data_table_row()."\n");
$i++;
@@ -7264,7 +7984,8 @@ sub csv_samples_select_table {
my ($r,$records,$d) = @_;
my $i=0;
#
- my $samples = &get_samples($records,3);
+ my $max_samples = 5;
+ my $samples = &get_samples($records,$max_samples);
$r->print(&start_data_table().
&start_data_table_header_row().''.
&mt('Field').' '.&mt('Samples').' '.
@@ -7280,7 +8001,7 @@ sub csv_samples_select_table {
$display.'');
}
$r->print('');
- foreach my $line (0..2) {
+ foreach my $line (0..($max_samples-1)) {
if (defined($samples->[$line]{$key})) {
$r->print($samples->[$line]{$key}." \n");
}
@@ -7891,7 +8612,9 @@ defdom (domain for which to retrieve con
origmail (scalar - email address of recipient from loncapa.conf,
i.e., predates configuration by DC via domainprefs.pm
-Returns: comma separated list of addresses to which to send e-mail.
+Returns: comma separated list of addresses to which to send e-mail.
+
+=back
=cut
@@ -7919,8 +8642,10 @@ sub build_recipient_list {
} elsif ($origmail ne '') {
push(@recipients,$origmail);
}
- if ($defmail ne '') {
- push(@recipients,$defmail);
+ if (defined($defmail)) {
+ if ($defmail ne '') {
+ push(@recipients,$defmail);
+ }
}
if ($otheremails) {
my @others;
@@ -7942,13 +8667,347 @@ sub build_recipient_list {
############################################################
############################################################
+=pod
+
+=head1 Course Catalog Routines
+
+=over 4
+
+=item * &gather_categories()
+
+Converts category definitions - keys of categories hash stored in
+coursecategories in configuration.db on the primary library server in a
+domain - to an array. Also generates javascript and idx hash used to
+generate Domain Coordinator interface for editing Course Categories.
+
+Inputs:
+
+categories (reference to hash of category definitions).
+
+cats (reference to array of arrays/hashes which encapsulates hierarchy of
+ categories and subcategories).
+
+idx (reference to hash of counters used in Domain Coordinator interface for
+ editing Course Categories).
+
+jsarray (reference to array of categories used to create Javascript arrays for
+ Domain Coordinator interface for editing Course Categories).
+
+Returns: nothing
+
+Side effects: populates cats, idx and jsarray.
+
+=cut
+
+sub gather_categories {
+ my ($categories,$cats,$idx,$jsarray) = @_;
+ my %counters;
+ my $num = 0;
+ foreach my $item (keys(%{$categories})) {
+ my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$item);
+ if ($container eq '' && $depth == 0) {
+ $cats->[$depth][$categories->{$item}] = $cat;
+ } else {
+ $cats->[$depth]{$container}[$categories->{$item}] = $cat;
+ }
+ my ($escitem,$tail) = split(/:/,$item,2);
+ if ($counters{$tail} eq '') {
+ $counters{$tail} = $num;
+ $num ++;
+ }
+ if (ref($idx) eq 'HASH') {
+ $idx->{$item} = $counters{$tail};
+ }
+ if (ref($jsarray) eq 'ARRAY') {
+ push(@{$jsarray->[$counters{$tail}]},$item);
+ }
+ }
+ return;
+}
+
+=pod
+
+=item * &extract_categories()
+
+Used to generate breadcrumb trails for course categories.
+
+Inputs:
+
+categories (reference to hash of category definitions).
+
+cats (reference to array of arrays/hashes which encapsulates hierarchy of
+ categories and subcategories).
+
+trails (reference to array of breacrumb trails for each category).
+
+allitems (reference to hash - key is category key
+ (format: escaped(name):escaped(parent category):depth in hierarchy).
+
+idx (reference to hash of counters used in Domain Coordinator interface for
+ editing Course Categories).
+
+jsarray (reference to array of categories used to create Javascript arrays for
+ Domain Coordinator interface for editing Course Categories).
+
+subcats (reference to hash of arrays containing all subcategories within each
+ category, -recursive)
+
+Returns: nothing
+
+Side effects: populates trails and allitems hash references.
+
+=cut
+
+sub extract_categories {
+ my ($categories,$cats,$trails,$allitems,$idx,$jsarray,$subcats) = @_;
+ if (ref($categories) eq 'HASH') {
+ &gather_categories($categories,$cats,$idx,$jsarray);
+ if (ref($cats->[0]) eq 'ARRAY') {
+ for (my $i=0; $i<@{$cats->[0]}; $i++) {
+ my $name = $cats->[0][$i];
+ my $item = &escape($name).'::0';
+ my $trailstr;
+ if ($name eq 'instcode') {
+ $trailstr = &mt('Official courses (with institutional codes)');
+ } else {
+ $trailstr = $name;
+ }
+ if ($allitems->{$item} eq '') {
+ push(@{$trails},$trailstr);
+ $allitems->{$item} = scalar(@{$trails})-1;
+ }
+ my @parents = ($name);
+ if (ref($cats->[1]{$name}) eq 'ARRAY') {
+ for (my $j=0; $j<@{$cats->[1]{$name}}; $j++) {
+ my $category = $cats->[1]{$name}[$j];
+ if (ref($subcats) eq 'HASH') {
+ push(@{$subcats->{$item}},&escape($category).':'.&escape($name).':1');
+ }
+ &recurse_categories($cats,2,$category,$trails,$allitems,\@parents,$subcats);
+ }
+ } else {
+ if (ref($subcats) eq 'HASH') {
+ $subcats->{$item} = [];
+ }
+ }
+ }
+ }
+ }
+ return;
+}
+
+=pod
+
+=item *&recurse_categories()
+
+Recursively used to generate breadcrumb trails for course categories.
+
+Inputs:
+
+cats (reference to array of arrays/hashes which encapsulates hierarchy of
+ categories and subcategories).
+
+depth (current depth in hierarchy of categories and sub-categories - 0 indexed).
+
+category (current course category, for which breadcrumb trail is being generated).
+
+trails (reference to array of breadcrumb trails for each category).
+
+allitems (reference to hash - key is category key
+ (format: escaped(name):escaped(parent category):depth in hierarchy).
+
+parents (array containing containers directories for current category,
+ back to top level).
+
+Returns: nothing
+
+Side effects: populates trails and allitems hash references
+
+=cut
+
+sub recurse_categories {
+ my ($cats,$depth,$category,$trails,$allitems,$parents,$subcats) = @_;
+ my $shallower = $depth - 1;
+ if (ref($cats->[$depth]{$category}) eq 'ARRAY') {
+ for (my $k=0; $k<@{$cats->[$depth]{$category}}; $k++) {
+ my $name = $cats->[$depth]{$category}[$k];
+ my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower;
+ my $trailstr = join(' -> ',(@{$parents},$category));
+ if ($allitems->{$item} eq '') {
+ push(@{$trails},$trailstr);
+ $allitems->{$item} = scalar(@{$trails})-1;
+ }
+ my $deeper = $depth+1;
+ push(@{$parents},$category);
+ if (ref($subcats) eq 'HASH') {
+ my $subcat = &escape($name).':'.$category.':'.$depth;
+ for (my $j=@{$parents}; $j>=0; $j--) {
+ my $higher;
+ if ($j > 0) {
+ $higher = &escape($parents->[$j]).':'.
+ &escape($parents->[$j-1]).':'.$j;
+ } else {
+ $higher = &escape($parents->[$j]).'::'.$j;
+ }
+ push(@{$subcats->{$higher}},$subcat);
+ }
+ }
+ &recurse_categories($cats,$deeper,$name,$trails,$allitems,$parents,
+ $subcats);
+ pop(@{$parents});
+ }
+ } else {
+ my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower;
+ my $trailstr = join(' -> ',(@{$parents},$category));
+ if ($allitems->{$item} eq '') {
+ push(@{$trails},$trailstr);
+ $allitems->{$item} = scalar(@{$trails})-1;
+ }
+ }
+ return;
+}
+
+=pod
+
+=item *&assign_categories_table()
+
+Create a datatable for display of hierarchical categories in a domain,
+with checkboxes to allow a course to be categorized.
+
+Inputs:
+
+cathash - reference to hash of categories defined for the domain (from
+ configuration.db)
+
+currcat - scalar with an & separated list of categories assigned to a course.
+
+Returns: $output (markup to be displayed)
+
+=cut
+
+sub assign_categories_table {
+ my ($cathash,$currcat) = @_;
+ my $output;
+ if (ref($cathash) eq 'HASH') {
+ my (@cats,@trails,%allitems,%idx,@jsarray,@path,$maxdepth);
+ &extract_categories($cathash,\@cats,\@trails,\%allitems,\%idx,\@jsarray);
+ $maxdepth = scalar(@cats);
+ if (@cats > 0) {
+ my $itemcount = 0;
+ if (ref($cats[0]) eq 'ARRAY') {
+ $output = &Apache::loncommon::start_data_table();
+ my @currcategories;
+ if ($currcat ne '') {
+ @currcategories = split('&',$currcat);
+ }
+ for (my $i=0; $i<@{$cats[0]}; $i++) {
+ my $parent = $cats[0][$i];
+ my $css_class = $itemcount%2?' class="LC_odd_row"':'';
+ next if ($parent eq 'instcode');
+ my $item = &escape($parent).'::0';
+ my $checked = '';
+ if (@currcategories > 0) {
+ if (grep(/^\Q$item\E$/,@currcategories)) {
+ $checked = ' checked="checked" ';
+ }
+ }
+ $output .= '