Diff for /loncom/interface/domainprefs.pm between versions 1.47 and 1.48

version 1.47, 2008/05/01 00:01:16 version 1.48, 2008/05/07 23:01:50
Line 37  use Apache::loncommon(); Line 37  use Apache::loncommon();
 use Apache::lonhtmlcommon();  use Apache::lonhtmlcommon();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonmsg();  use Apache::lonmsg();
 use LONCAPA();  use LONCAPA;
 use LONCAPA::Enrollment;  use LONCAPA::Enrollment;
 use File::Copy;  use File::Copy;
 use Locale::Language;  use Locale::Language;
Line 70  sub handler { Line 70  sub handler {
     my %domconfig =      my %domconfig =
       &Apache::lonnet::get_dom('configuration',['login','rolecolors',        &Apache::lonnet::get_dom('configuration',['login','rolecolors',
                 'quotas','autoenroll','autoupdate','directorysrch',                  'quotas','autoenroll','autoupdate','directorysrch',
                 'usercreation','usermodification','contacts','defaults','scantron'],                  'usercreation','usermodification','contacts','defaults',
                 $dom);                  'scantron','coursecategories'],$dom);
     my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',      my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
                        'autoupdate','directorysrch','contacts',                         'autoupdate','directorysrch','contacts',
                        'usercreation','usermodification','scantron');                         'usercreation','usermodification','scantron',
                          'coursecategories');
     my %prefs = (      my %prefs = (
         'rolecolors' =>          'rolecolors' =>
                    { text => 'Default color schemes',                     { text => 'Default color schemes',
Line 158  sub handler { Line 159  sub handler {
                                  col2 => '',                                   col2 => '',
                               }],                                }],
                   },                    },
           'coursecategories' => 
                     { text => 'Cataloging of courses',
                       help => 'Domain_Course_Catalog',
                       header => [  {col1 => 'Categories',
                                     col2 => '',
                                 }],
                     }
     );      );
     my @roles = ('student','coordinator','author','admin');      my @roles = ('student','coordinator','author','admin');
     my @actions = &Apache::loncommon::get_env_multiple('form.actions');      my @actions = &Apache::loncommon::get_env_multiple('form.actions');
Line 316  sub handler { Line 324  sub handler {
         $r->print('</div><div class="LC_clear_float_footer"></div><h3>'.          $r->print('</div><div class="LC_clear_float_footer"></div><h3>'.
                   &mt('Display options').'</h3>'."\n".                    &mt('Display options').'</h3>'."\n".
                   '<p><span class="LC_nobreak">'.&mt('Display using: ')."\n".                    '<p><span class="LC_nobreak">'.&mt('Display using: ')."\n".
                   '<label><input type="radio" name="numcols" value="1">'.                    '<label><input type="radio" name="numcols" value="1" />'.
                   &mt('one column').'</label>&nbsp;&nbsp;'.                    &mt('one column').'</label>&nbsp;&nbsp;<label>'.
                   '<input type="radio" name="numcols" value="2">'.                    '<input type="radio" name="numcols" value="2" />'.
                   &mt('two columns').'</label></span></p>');                    &mt('two columns').'</label></span></p>');
         $r->print(&print_footer($r,$phase,'display','Go'));          $r->print(&print_footer($r,$phase,'display','Go'));
         $r->print('</form>');          $r->print('</form>');
Line 352  sub process_changes { Line 360  sub process_changes {
     } elsif ($action eq 'defaults') {      } elsif ($action eq 'defaults') {
         $output = &modify_defaults($dom,$r);          $output = &modify_defaults($dom,$r);
     } elsif ($action eq 'scantron') {      } elsif ($action eq 'scantron') {
         $output = &modify_scantron($r,$dom,$confname,\%domconfig);          $output = &modify_scantron($r,$dom,$confname,%domconfig);
       } elsif ($action eq 'coursecategories') {
           $output = &modify_coursecategories($dom,%domconfig);
     }      }
     return $output;      return $output;
 }  }
Line 460  sub print_config_box { Line 470  sub print_config_box {
             $output .= '              $output .= '
               <td class="LC_left_item">'.$item->{'header'}->[0]->{'col1'}.'</td>';                <td class="LC_left_item">'.$item->{'header'}->[0]->{'col1'}.'</td>';
         }          }
           my $colspan = ($action eq 'coursecategories')?' colspan="2"':'';
         $output .= '          $output .= '
               <td class="LC_right_item">'.$item->{'header'}->[0]->{'col2'}.'</td>                <td class="LC_right_item"'.$colspan.'>'.$item->{'header'}->[0]->{'col2'}.'</td>
              </tr>';               </tr>';
         $rowtotal ++;                $rowtotal ++;
         if ($action eq 'login') {          if ($action eq 'login') {
             $output .= &print_login($dom,$confname,$phase,$settings,\$rowtotal);              $output .= &print_login($dom,$confname,$phase,$settings,\$rowtotal);
         } elsif ($action eq 'quotas') {          } elsif ($action eq 'quotas') {
Line 478  sub print_config_box { Line 489  sub print_config_box {
             $output .= &print_defaults($dom,\$rowtotal);              $output .= &print_defaults($dom,\$rowtotal);
         } elsif ($action eq 'scantron') {          } elsif ($action eq 'scantron') {
             $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);              $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
           } elsif ($action eq 'coursecategories'){
               $output .= &print_coursecategories($dom,$item,$settings,\$rowtotal);
         }          }
     }      }
     $output .= '      $output .= '
Line 498  function changePage(formname,newphase) { Line 511  function changePage(formname,newphase) {
     numchecked = 0;      numchecked = 0;
     if (formname == document.pickactions) {      if (formname == document.pickactions) {
         if (formname.actions.length > 0) {          if (formname.actions.length > 0) {
             for (var i = 0; i <formname.actions.length; i++) {              for (var i = 0; i<formname.actions.length; i++) {
                 if (formname.actions[i].checked) {                  if (formname.actions[i].checked) {
                     numchecked ++;                      numchecked ++;
                 }                  }
Line 1699  sub usercreation_types { Line 1712  sub usercreation_types {
                     none       => 'None',                      none       => 'None',
     );      );
     return %lt;      return %lt;
 }   }
   
 sub authtype_names {  sub authtype_names {
     my %lt = &Apache::lonlocal::texthash(      my %lt = &Apache::lonlocal::texthash(
Line 1922  sub legacy_scantronformat { Line 1935  sub legacy_scantronformat {
     return ($url,$error);      return ($url,$error);
 }  }
   
   sub print_coursecategories { 
       my ($dom,$item,$settings,$rowtotal) = @_;
       my ($datatable,$css_class);
       my $itemcount = 1;
       # FIXME Need to add javascrpt to update other select boxes when one is changed.
       if (ref($settings) eq 'HASH') {
           my (@cats,@trails,%allitems);
           &extract_categories($settings,\@cats,\@trails,\%allitems);
           my $maxdepth = scalar(@cats); 
           my $colattrib = '';
           if ($maxdepth > 2) {
               $colattrib = ' colspan="2" ';
           }
           my @path;
           if (@cats > 0) {
               if (ref($cats[0]) eq 'ARRAY') {
                   my $numtop = @{$cats[0]};
                   my $maxnum = $numtop;
                   if ((!grep(/^instcode$/,@{$cats[0]})) || ($settings->{'instcode::0'} eq '')) {
                       $maxnum ++;
                   }
                   for (my $i=0; $i<$numtop; $i++) {
                       my $parent = $cats[0][$i];
                       $css_class = $itemcount%2?' class="LC_odd_row"':'';
                       my $item = &escape($parent).'::0';
                       $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                                     .'<select name="'.$item.'">';
                       for (my $k=0; $k<=$maxnum; $k++) {
                           my $vpos = $k+1;
                           my $selstr;
                           if ($k == $i) {
                               $selstr = ' selected="selected" ';
                           }
                           $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                       }
                       $datatable .= '</select></td><td>';
                       if ($parent eq 'instcode') {
                           $datatable .=  '<span class="LC_nobreak">'.&mt('Official courses')
                                          .'</span><br /><span class="LC_nobreak">('
                                          .&mt('with institutional codes').')</span></td>'
                                          .'<td'.$colattrib.'><span class="LC_nobreak"><label><input type="radio" name="instcode" value="1" checked="checked" />'
                                           .&mt('Display').'</label>&nbsp;'
                                           .'<label><input type="radio" name="instcode" value="0" />'
                                           .&mt('Do not display').'</label></span></td>';
                       } else {
                           $datatable .= $parent
                                         .'&nbsp;<label><input type="checkbox" name="deletecategory" '
                                         .'value="'.$item.'" />'.&mt('Delete').'</label></span></td>';
                       }
                       my $depth = 1;
                       push(@path,$parent);
                       $datatable .= &build_category_rows($itemcount,\@cats,$depth,$parent,\@path);
                       pop(@path);
                       $datatable .= '</tr><tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr>';
                       $itemcount ++;
                   }
                   $css_class = $itemcount%2?' class="LC_odd_row"':'';
                   $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="addcategory_pos">';
                   for (my $k=0; $k<=$maxnum; $k++) {
                       my $vpos = $k+1;
                       my $selstr;
                       if ($k == $numtop) {
                           $selstr = ' selected="selected" ';
                       }
                       $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                   }
                   $datatable .= '</select></span></td><td colspan="2">'.&mt('New:').'&nbsp;'
                                 .'<input type="text" size="20" name="addcategory_name" value="" /></td>'
                                 .'</tr>'."\n";
                   $itemcount ++;
                   if ((!grep(/^instcode$/,@{$cats[0]})) || ($settings->{'instcode::0'} eq '')) {
                       $css_class = $itemcount%2?' class="LC_odd_row"':'';
                       $datatable .= '<tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr><tr '.$css_class.'><td>'.
                                     '<span class="LC_nobreak"><select name="instcode_pos">';
                       for (my $k=0; $k<=$maxnum; $k++) {
                           my $vpos = $k+1;
                           my $selstr;
                           if ($k == $maxnum) {
                               $selstr = ' selected="selected" ';
                           }
                           $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
                       }
                       $datatable .= '</select></span></td><td><span class="LC_nobreak">'
                                     .&mt('Official courses').'</span>'.'<br /><span class="LC_nobreak">('
                                     .&mt('with institutional codes').')</span></td>'
                                     .'<td><span class="LC_nobreak"><label><input type="radio" name="instcode" value="1" />'
                                     .&mt('Display').'</label>&nbsp;'
                                     .'<label><input type="radio" name="instcode" value="0" checked="checked"/>'
                                     .&mt('Do not display').'</label></span></td></tr>';
                   }
               }
           } else {
               $datatable .= &initialize_categories($itemcount);
           }
       } else {
           $datatable .= '<td class="LC_right_item">'.$item->{'header'}->[0]->{'col2'}.'</td>'
                         .&initialize_categories($itemcount);
       }
       $$rowtotal += $itemcount;
       return $datatable;
   }
   
   sub initialize_categories {
       my ($itemcount) = @_;
       my $datatable;
       my $css_class = $itemcount%2?' class="LC_odd_row"':'';
       $datatable = '<tr '.$css_class.'><td><span class="LC_nobreak">'
                    .'<select name="instcode_pos"><option value="0" selected="selected">1</option>'
                    .'<option value="1">2</option></select>&nbsp;'
                    .&mt('Official courses (with institutional codes)')
                    .'</span></td><td><span class="LC_nobreak">'
                    .'<label><input type="radio" name="instcode" value="1" checked="checked" />'
                    .&mt('Display').'</label>&nbsp;<label>'
                    .'<input type="radio" name="instcode" value="0" />'.&mt('Do not display')
                    .'</label></span></td></tr>';
       $itemcount ++;
       $css_class = $itemcount%2?' class="LC_odd_row"':'';
       $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
                     .'<select name="addcategory_pos"><option value="0">1</option>'
                     .'<option value="1" selected="selected">2</option></select>&nbsp;'
                     .&mt('Add category').'</td><td>'.&mt('Name:')
                     .'&nbsp;<input type="text" size="20" name="addcategory_name" value="" /></td></tr>';
       return $datatable;
   }
   
   sub build_category_rows {
       my ($itemcount,$cats,$depth,$parent,$path) = @_;
       my ($text,$name,$item);
       if (ref($cats) eq 'ARRAY') {
           my $maxdepth = scalar(@{$cats});
           if (ref($cats->[$depth]) eq 'HASH') {
               if (ref($cats->[$depth]{$parent}) eq 'ARRAY') {
                   my $numchildren = @{$cats->[$depth]{$parent}};
                   my $css_class = $itemcount%2?' class="LC_odd_row"':'';
                   $text .= '<td><table class="LC_datatable">';
                   for (my $j=0; $j<=$numchildren; $j++) {
                       if ($j == $numchildren) {
                           my $higher = $depth-1;
                           if ($higher == 0) {
                               $name = &escape($parent).'::'.$higher;
                           } else {
                               if (ref($path) eq 'ARRAY') {
                                   $name = &escape($parent).':'.&escape($path->[-2]).':'.$higher;
                               }
                           }
                           $item = 'addcategory_pos_'.$name;
                       } else {
                           $name = $cats->[$depth]{$parent}[$j];
                           $item = &escape($name).':'.&escape($parent).':'.$depth;
                       }
                       $text .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="'.$item.'">';
                       for (my $i=0; $i<=$numchildren; $i++) {
                           my $vpos = $i+1;
                           my $selstr;
                           if ($j == $i) {
                               $selstr = ' selected="selected" ';
                           }
                           $text .= '<option value="'.$i.'"'.$selstr.'>'.$vpos.'</option>';
                       }
                       $text .= '</select>&nbsp;';
                       if ($j < $numchildren) {
                           my $deeper = $depth+1;
                           $text .= $name.'&nbsp;'
                                    .'<label><input type="checkbox" name="deletecategory" value="'
                                    .$item.'" />'.&mt('Delete').'</label></span></td><td>';
                           if(ref($path) eq 'ARRAY') {
                               push(@{$path},$name);
                               $text .= &build_category_rows($itemcount,$cats,$deeper,$name,$path);
                               pop(@{$path});
                           }
                       } else {
                           $text .= &mt('New:').'&nbsp;</span><input type="textbox" size="20" name="addcategory_name_';
                           if ($j == $numchildren) {
                               $text .= $name;
                           } else {
                               $text .= $item;
                           }
                           $text .= '" value="" />';
                       }
                       $text .= '</td></tr>';
                   }
                   $text .= '</table></td>';
               } else {
                   my $higher = $depth-1;
                   if ($higher == 0) {
                       $name = &escape($parent).'::'.$higher;
                   } else {
                       if (ref($path) eq 'ARRAY') {
                           $name = &escape($parent).':'.&escape($path->[-2]).':'.$higher;
                       }
                   }
                   my $colspan;
                   if ($parent ne 'instcode') {
                       $colspan = $maxdepth - $depth - 1;
                       $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="textbox" size="20" name="subcat_'.$name.'" value="" /></td>';
                   }
               }
           }
       }
       return $text;
   }
   
 sub modifiable_userdata_row {  sub modifiable_userdata_row {
     my ($context,$role,$settings,$numinrow,$rowcount) = @_;      my ($context,$role,$settings,$numinrow,$rowcount) = @_;
     my $rolename;      my $rolename;
Line 2438  sub default_change_checker { Line 2653  sub default_change_checker {
     if ($confhash->{$role}{'font'}) {      if ($confhash->{$role}{'font'}) {
         $changes->{$role}{'font'} = 1;          $changes->{$role}{'font'} = 1;
     }      }
 }   }
   
 sub display_colorchgs {  sub display_colorchgs {
     my ($dom,$changes,$roles,$confhash) = @_;      my ($dom,$changes,$roles,$confhash) = @_;
Line 3753  sub modify_defaults { Line 3968  sub modify_defaults {
 }  }
   
 sub modify_scantron {  sub modify_scantron {
     my ($r,$dom,$confname,$domconfig) = @_;      my ($r,$dom,$confname,%domconfig) = @_;
     my ($resulttext,%confhash,%changes,$errors);      my ($resulttext,%confhash,%changes,$errors);
     my $custom = 'custom.tab';      my $custom = 'custom.tab';
     my $default = 'default.tab';      my $default = 'default.tab';
Line 3772  sub modify_scantron { Line 3987  sub modify_scantron {
                                      $confname,'scantron','','',$custom);                                       $confname,'scantron','','',$custom);
                     if ($result eq 'ok') {                      if ($result eq 'ok') {
                         $confhash{'scantron'}{'scantronformat'} = $scantronurl;                          $confhash{'scantron'}{'scantronformat'} = $scantronurl;
                         $changes{'scantron'}{'scantronformat'} = 1;                          $changes{'scantronformat'} = 1;
                     } else {                      } else {
                         $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$custom,$result);                          $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$custom,$result);
                     }                      }
Line 3788  sub modify_scantron { Line 4003  sub modify_scantron {
             $errors .= '<li><span class="LC_error">'.$error.'</span></li>';              $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
         }          }
     }      }
     if (ref($domconfig) eq 'HASH') {      if (ref($domconfig{'scantron'}) eq 'HASH') {
         if (ref($domconfig->{'scantron'}) eq 'HASH') {          if ($domconfig{'scantron'}{'scantronformat'} ne '') {
             if ($domconfig->{'scantron'}{'scantronformat'} ne '') {              if ($env{'form.scantronformat_del'}) {
                 if ($env{'form.scantronformat_del'}) {                  $confhash{'scantron'}{'scantronformat'} = '';
                     $confhash{'scantron'}{'scantronformat'} = '';                  $changes{'scantronformat'} = 1;
                     $changes{'scantron'}{'scantronformat'} = 1;  
                 }  
             }              }
         }          }
     }      }
Line 3803  sub modify_scantron { Line 4016  sub modify_scantron {
                                                  $dom);                                                   $dom);
         if ($putresult eq 'ok') {          if ($putresult eq 'ok') {
             if (keys(%changes) > 0) {              if (keys(%changes) > 0) {
                 $resulttext = &mt('Changes made:').'<ul>';                  if (ref($confhash{'scantron'}) eq 'HASH') {
                 if (ref($changes{'scantron'}) eq 'HASH') {                      $resulttext = &mt('Changes made:').'<ul>';
                     if ($changes{'scantron'}{'scantronformat'}) {                       if ($confhash{'scantron'}{'scantronformat'} eq '') {
                         if ($confhash{'scantron'}{'scantronformat'} eq '') {                          $resulttext .= '<li>'.&mt('[_1] scantron format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>';
                             $resulttext .= '<li>'.&mt('[_1] scantron format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>';                      } else {
                         } else {                          $resulttext .= '<li>'.&mt('Custom scantron format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>';
                             $resulttext .= '<li>'.&mt('Custom scantron format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>';  
                         }  
                     }                      }
                       $resulttext .= '</ul>';
                   } else {
                       $resulttext = &mt('Changes made to scantron format file.');
                 }                  }
                 $resulttext .= '</ul>';                  $resulttext .= '</ul>';
                 &Apache::loncommon::devalidate_domconfig_cache($dom);                  &Apache::loncommon::devalidate_domconfig_cache($dom);
Line 3832  sub modify_scantron { Line 4046  sub modify_scantron {
     return $resulttext;      return $resulttext;
 }  }
   
   sub modify_coursecategories {
       my ($dom,%domconfig) = @_;
       my ($resulttext,%deletions,%reorderings,%needreordering,%adds,$errors);
       my @deletecategory = &Apache::loncommon::get_env_multiple('form.deletecategory');
       if (($domconfig{'coursecategories'}{'instcode::0'} ne '')  && ($env{'form.instcode'} == 0)) {
           push (@deletecategory,'instcode::0');
       }
       my (@predelcats,@predeltrails,%predelallitems);
       if (ref($domconfig{'coursecategories'}) eq 'HASH') {
           if (@deletecategory > 0) {
               #FIXME Need to remove category from all courses using a deleted category 
               &extract_categories($domconfig{'coursecategories'},\@predelcats,\@predeltrails,\%predelallitems);
               foreach my $item (@deletecategory) {
                   if ($domconfig{'coursecategories'}{$item} ne '') {
                       delete($domconfig{'coursecategories'}{$item});
                       $deletions{$item} = 1;
                       &recurse_cat_deletes($item,$domconfig{'coursecategories'},
                                            \%deletions);
                   }
               }
           }
           foreach my $item (keys(%{$domconfig{'coursecategories'}})) {
               my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$item);
               if ($domconfig{'coursecategories'}{$item} ne $env{'form.'.$item}) {
                   $reorderings{$item} = 1;
                   $domconfig{'coursecategories'}{$item} = $env{'form.'.$item};
               }
               if ($env{'form.addcategory_name_'.$item} ne '') {
                   my $newcat = $env{'form.addcategory_name_'.$item};
                   my $newdepth = $depth+1;
                   my $newitem = &escape($newcat).':'.&escape($cat).':'.$newdepth;
                   $domconfig{'coursecategories'}{$newitem} = $env{'form.addcategory_pos_'.$item};
                   $adds{$newitem} = 1; 
               }
               if ($env{'form.subcat_'.$item} ne '') {
                   my $newcat = $env{'form.subcat_'.$item};
                   my $newdepth = $depth+1;
                   my $newitem = &escape($newcat).':'.&escape($cat).':'.$newdepth;
                   $domconfig{'coursecategories'}{$newitem} = 0;
                   $adds{$newitem} = 1;
               }
           }
       }
       if ($env{'form.instcode'} eq '1') {
           if (ref($domconfig{'coursecategories'}) eq 'HASH') {
               my $newitem = 'instcode::0';
               if ($domconfig{'coursecategories'}{$newitem} eq '') {  
                   $domconfig{'coursecategories'}{$newitem} = $env{'form.instcode_pos'};
                   $adds{$newitem} = 1;
               }
           } else {
               my $newitem = 'instcode::0';
               $domconfig{'coursecategories'}{$newitem} = $env{'form.instcode_pos'};
               $adds{$newitem} = 1;
           }
       }
       if ($env{'form.addcategory_name'} ne '') {
           my $newitem = &escape($env{'form.addcategory_name'}).'::0';
           $domconfig{'coursecategories'}{$newitem} = $env{'form.addcategory_pos'};
           $adds{$newitem} = 1;
       }
       if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) {
           my %sort_by_deltrail;
           if (keys(%deletions) > 0) {
               foreach my $key (keys(%deletions)) {
                   if ($predelallitems{$key} ne '') {
                       $sort_by_deltrail{$predelallitems{$key}} = $predeltrails[$predelallitems{$key}];
                   }
               }
           }
           my (@chkcats,@chktrails,%chkallitems);
           &extract_categories($domconfig{'coursecategories'},\@chkcats,\@chktrails,\%chkallitems);
           if (ref($chkcats[0]) eq 'ARRAY') {
               my $depth = 0;
               my $chg = 0;
               for (my $i=0; $i<@{$chkcats[0]}; $i++) {
                   my $name = $chkcats[0][$i];
                   my $item;
                   if ($name eq '') {
                       $chg ++;
                   } else {
                       $item = &escape($name).'::0';
                       if ($chg) {
                           $domconfig{'coursecategories'}{$item} -= $chg;
                       }
                       $depth ++; 
                       &recurse_check(\@chkcats,$domconfig{'coursecategories'},$depth,$name);
                       $depth --;
                   }
               }
           }
           my $putresult = &Apache::lonnet::put_dom('configuration',\%domconfig,$dom);
           my (@cats,@trails,%allitems);
           &extract_categories($domconfig{'coursecategories'},\@cats,\@trails,\%allitems);
           if ($putresult eq 'ok') {
               $resulttext = &mt('Changes made:').'<ul>';
               if (keys(%deletions) > 0) {
                   $resulttext .= '<li>'.&mt('Deleted categories:').'<ul>';
                   foreach my $predeltrail (sort {$a <=> $b } (keys(%sort_by_deltrail))) { 
                       $resulttext .= '<li>'.$predeltrails[$predeltrail].'</li>';
                   }
                   $resulttext .= '</ul></li>';
               }
               if (keys(%reorderings) > 0) {
                   my %sort_by_trail;
                   $resulttext .= '<li>'.&mt('Reordered categories:').'<ul>';
                   foreach my $key (keys(%reorderings)) {
                       if ($allitems{$key} ne '') {
                           $sort_by_trail{$allitems{$key}} = $trails[$allitems{$key}];
                       }
                   }
                   foreach my $trail (sort {$a <=> $b } (keys(%sort_by_trail))) {
                       $resulttext .= '<li>'.$trails[$trail].'</li>';
                   }
                   $resulttext .= '</ul></li>';
               }
               if (keys(%adds) > 0) {
                   my %sort_by_trail;
                   $resulttext .= '<li>'.&mt('Added categories:').'<ul>';
                   foreach my $key (keys(%adds)) {
                       if ($allitems{$key} ne '') {
                           $sort_by_trail{$allitems{$key}} = $trails[$allitems{$key}];
                       }
                   }
                   foreach my $trail (sort {$a <=> $b } (keys(%sort_by_trail))) {
                       $resulttext .= '<li>'.$trails[$trail].'</li>';
                   }
                   $resulttext .= '</ul></li>';
               }
               $resulttext .= '</ul>';
           } else {
               $resulttext = '<span class="LC_error">'.
                   &mt('An error occurred: [_1]',$putresult).'</span>';
           }
       } else {
           $resulttext = &mt('No changes made to course categories');
       }
       return $resulttext;
   }
   
   sub recurse_check {
       my ($chkcats,$categories,$depth,$name) = @_;
       if (ref($chkcats->[$depth]{$name}) eq 'ARRAY') {
           my $chg = 0;
           for (my $j=0; $j<@{$chkcats->[$depth]{$name}}; $j++) {
               my $category = $chkcats->[$depth]{$name}[$j];
               my $item;
               if ($category eq '') {
                   $chg ++;
               } else {
                   my $deeper = $depth + 1;
                   $item = &escape($category).':'.&escape($name).':'.$depth;
                   if ($chg) {
                       $categories->{$item} -= $chg;
                   }
                   &recurse_check($chkcats,$categories,$deeper,$category);
                   $deeper --;
               }
           }
       }
       return;
   }
   
   sub recurse_cat_deletes {
       my ($item,$coursecategories,$deletions) = @_;
       my ($deleted,$container,$depth) = map { &unescape($_); } split(/:/,$item);
       my $subdepth = $depth + 1;
       if (ref($coursecategories) eq 'HASH') {
           foreach my $subitem (keys(%{$coursecategories})) {
               my ($child,$parent,$itemdepth) = map { &unescape($_); } split(/:/,$subitem);
               if (($parent eq $deleted) && ($itemdepth == $subdepth)) {
                   delete($coursecategories->{$subitem});
                   $deletions->{$subitem} = 1;
                   &recurse_cat_deletes($subitem,$coursecategories,$deletions);
               }  
           }
       }
       return;
   }
   
   sub extract_categories {
       my ($categories,$cats,$trails,$allitems) = @_;
       if (ref($categories) eq 'HASH') {
           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;
               }
           }
           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];
                           &recurse_categories($cats,2,$category,$trails,$allitems,\@parents);
                       }
                   }
               }
           }
       }
       return;
   }
   
   sub recurse_categories {
       my ($cats,$depth,$category,$trails,$allitems,$parents) = @_;
       if (ref($cats->[$depth]{$category}) eq 'ARRAY') {
           for (my $k=0; $k<@{$cats->[$depth]{$category}}; $k++) {
               my $shallower = $depth - 1;
               my $name = $cats->[$depth]{$category}[$k];
               my $item = &escape($category).':'.&escape($parents->[-1]).':'.$shallower;
               my $trailstr = join(' -&gt; ',(@{$parents},$category));
               if ($allitems->{$item} eq '') { 
                   push(@{$trails},$trailstr);
                   $allitems->{$item} = scalar(@{$trails})-1;
               }
               my $deeper = $depth+1;
               push(@{$parents},$category);
               &recurse_categories($cats,$deeper,$name,$trails,$allitems,$parents);
               pop(@{$parents});
           }
       } else {
           $depth --;
           my $item = &escape($category).':'.&escape($parents->[-1]).':'.$depth;
           my $trailstr = join(' -&gt; ',(@{$parents},$category));
           if ($allitems->{$item} eq '') {
               push(@{$trails},$trailstr);
               $allitems->{$item} = scalar(@{$trails})-1;
           }
       }
       return;
   }
   
 1;  1;

Removed from v.1.47  
changed lines
  Added in v.1.48


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>