[LON-CAPA-cvs] cvs: loncom /interface lonmodifycourse.pm lonpickcourse.pm

raeburn raeburn@source.lon-capa.org
Fri, 31 Jul 2009 03:01:31 -0000


This is a MIME encoded message

--raeburn1249009291
Content-Type: text/plain

raeburn		Fri Jul 31 03:01:31 2009 EDT

  Modified files:              
    /loncom/interface	lonmodifycourse.pm lonpickcourse.pm 
  Log:
  - When used in course request or course creation context, courses display replaces select button with text warning for courses for which owner lacks cloning rights.
  - In those contexts can filter based on cloneability.
  - Hierarchy of linked select boxes used for institutional codes (with official/unofficial radio button selectors) now used for "Modify Course" function available to Domain Coordinator.
  - Eliminate "command" form element added in lonpickcourse.pm rev 1.84. Revert to check for g'osearch' form element to trigger search.
  -  No search if page updated by onchange event for Type or Domain 
     (as detected based on non-null value of updater form element).
  
  
--raeburn1249009291
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20090731030131.txt"

Index: loncom/interface/lonmodifycourse.pm
diff -u loncom/interface/lonmodifycourse.pm:1.45 loncom/interface/lonmodifycourse.pm:1.46
--- loncom/interface/lonmodifycourse.pm:1.45	Tue Jun  9 13:26:35 2009
+++ loncom/interface/lonmodifycourse.pm	Fri Jul 31 03:01:31 2009
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # handler for DC-only modifiable course settings
 #
-# $Id: lonmodifycourse.pm,v 1.45 2009/06/09 13:26:35 bisitz Exp $
+# $Id: lonmodifycourse.pm,v 1.46 2009/07/31 03:01:31 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -120,17 +120,30 @@
                       'instcodefilter','ownerfilter',
                       'coursefilter'];
     my $filter = {};
-    my $numtitles;
-    my $type = 'Course';
+    my ($numtitles,$type,$cctitle,$dctitle);
+    $type = $env{'form.type'};
+    if (!defined($env{'form.type'})) {
+        $type = 'Course';
+    }
     my $action = '/adm/modifycourse';
-    my $cctitle = &Apache::lonnet::plaintext('cc',$type);
-    my $dctitle = &Apache::lonnet::plaintext('dc');
-    $r->print(
-        '<h3>'.&mt('Search for a course in the [_1] domain',$domdesc).'</h3>'.
-        &mt('Actions available after searching for a course:').'<ul>'.  
-        '<li>'.&mt('Enter the course with the role of [_1]',$cctitle).'</li>'."\n".
-        '<li>'.&mt('View or modify course settings which only a [_1] may modify.'
-                  ,$dctitle).'</li>'."\n".'</ul>');
+    $cctitle = &Apache::lonnet::plaintext('cc',$type);
+    $dctitle = &Apache::lonnet::plaintext('dc');
+    $r->print(&Apache::lonpickcourse::js_changer());
+    if ($type eq 'Course') {
+        $r->print(
+            '<h3>'.&mt('Search for a course in the [_1] domain',$domdesc).'</h3>'.
+            &mt('Actions available after searching for a course:').'<ul>'.  
+            '<li>'.&mt('Enter the course with the role of [_1]',$cctitle).'</li>'."\n".
+            '<li>'.&mt('View or modify course settings which only a [_1] may modify.'
+                      ,$dctitle).'</li>'."\n".'</ul>');
+    } else {
+        $r->print(
+            '<h3>'.&mt('Search for a community in the [_1] domain',$domdesc).'</h3>'.
+            &mt('Actions available after searching for a community:').'<ul>'.          
+            '<li>'.&mt('Enter the community with the role of [_1]',$cctitle).'</li>'."\n".
+            '<li>'.&mt('View or modify community settings which only a [_1] may modify.'
+                      ,$dctitle).'</li>'."\n".'</ul>');
+    }   
     $r->print(&Apache::lonpickcourse::build_filters($filterlist,$type,
                              undef,undef,$filter,$action,\$numtitles,'modifycourse'));
 }
@@ -145,18 +158,20 @@
                       'ownerdomfilter','coursefilter'];
     my %filter;
     my $type = $env{'form.type'};
-    if ($type eq '') {
+    if (!defined($type)) {
         $type = 'Course';
     }
     my $action = '/adm/modifycourse';
     my $dctitle = &Apache::lonnet::plaintext('dc');
+    my $numtitles;
+    $r->print(&Apache::lonpickcourse::js_changer());
     $r->print(&mt('Revise your search criteria for this domain').' ('.$domdesc.').<br /><br />');
     $r->print(&Apache::lonpickcourse::build_filters($filterlist,$type,
-                                       undef,undef,\%filter,$action));
+                                       undef,undef,\%filter,$action,\$numtitles));
     $filter{'domainfilter'} = $dom;
     my %courses = &Apache::lonpickcourse::search_courses($r,$type,0,
-                                                         \%filter);
-    &Apache::lonpickcourse::display_matched_courses($r,$type,0,$action,undef,
+                                                         \%filter,$numtitles);
+    &Apache::lonpickcourse::display_matched_courses($r,$type,0,$action,undef,undef,undef,
                                                     %courses);
     return;
 }
@@ -1091,7 +1106,7 @@
 
 sub hidden_form_elements {
     my $hidden_elements = 
-      &Apache::lonhtmlcommon::echo_form_input(['gosearch','coursecode',
+      &Apache::lonhtmlcommon::echo_form_input(['gosearch','updater','coursecode',
           'prevphase','numlocalcc','courseowner','login','coursequota','intarg',
           'locarg','krbarg','krbver','counter','hidefromcat','usecategory'])."\n".
           '<input type="hidden" name="prevphase" value="'.$env{'form.phase'}.'" />';
@@ -1114,6 +1129,9 @@
         &Apache::lonhtmlcommon::clear_breadcrumbs();
 
         my $phase = $env{'form.phase'};
+        if ($env{'form.updater'}) {
+            $phase = '';
+        }
         if ($phase eq '') {
             &Apache::lonhtmlcommon::add_breadcrumb
             ({href=>"/adm/modifycourse",
Index: loncom/interface/lonpickcourse.pm
diff -u loncom/interface/lonpickcourse.pm:1.84 loncom/interface/lonpickcourse.pm:1.85
--- loncom/interface/lonpickcourse.pm:1.84	Wed Jul 29 22:32:44 2009
+++ loncom/interface/lonpickcourse.pm	Fri Jul 31 03:01:31 2009
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Pick a course
 #
-# $Id: lonpickcourse.pm,v 1.84 2009/07/29 22:32:44 raeburn Exp $
+# $Id: lonpickcourse.pm,v 1.85 2009/07/31 03:01:31 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -36,7 +36,7 @@
 use Apache::lonlocal;
 use Apache::longroup;
 use Apache::courseclassifier;
-use LONCAPA;
+use LONCAPA qw(:DEFAULT :match);
 
 sub handler {
     my $r = shift;
@@ -50,9 +50,9 @@
     &Apache::loncommon::get_unprocessed_cgi
         ($ENV{'QUERY_STRING'},['domainfilter','form','cnumelement',
 			       'cdomelement','cnameelement','roleelement',
-                               'multiple','type','setroles','fixeddom']);
+                               'multiple','type','setroles','fixeddom','cloner']);
     my ($type,$title,$jscript,$multelement,$multiple,$roleelement,
-        $lastaction,$autosubmit,$submitopener);
+        $lastaction,$autosubmit,$submitopener,$cloneruname,$clonerudom);
 
     # Get course type - Course or Community.
     $type = $env{'form.type'};
@@ -76,6 +76,17 @@
         $autosubmit = 'process_pick("'.$roledom.'")';
     }
 
+    # if called when a DC is creating a course
+    if ($env{'form.form'} eq 'ccrs') {
+        ($cloneruname,$clonerudom) = ($env{'form.cloner'} =~ /^($match_username):($match_domain)$/);
+    }
+
+    # if called when requesting a course
+    if ($env{'form.form'} eq 'requestcrs') {
+        $cloneruname = $env{'user.name'};
+        $clonerudom =  $env{'user.domain'};
+    }
+
     my $onlyown = 0;
     # if called to assign course-based portfolio access control
     if ((($env{'form.form'} eq 'portform') && (!$env{'user.adv'}))) {
@@ -93,7 +104,8 @@
         ($env{'form.pickedcourse'})) {
             $loaditem{'onload'} .= 'setSections()';
     }
-    $r->print(&Apache::loncommon::start_page($title,undef,
+    my $js = &js_changer();
+    $r->print(&Apache::loncommon::start_page($title,$js,
 					     {'add_entries' => \%loaditem,
 					      'no_nav_bar'  => 1, }));
 
@@ -114,7 +126,8 @@
     }
 
     # print javascript functions for choosing a course 
-    if (($env{'form.command'} eq 'gosearch') || $onlyown) {
+    if ((($env{'form.gosearch'}) && ($env{'form.updater'} eq '')) || 
+        $onlyown) {
         $r->print(&gochoose_javascript($type,$multiple,$autosubmit,$lastaction));
     }
     $r->print('<script type="text/javascript" language="Javascript">'.$jscript.
@@ -146,26 +159,51 @@
             exists($env{'user.role.dc./'.$env{'form.domainfilter'}.'/'})) {
             push(@{$filterlist},'coursefilter');
         }
+        if ($cloneruname ne '' && $clonerudom ne '') {
+            push(@{$filterlist},'cloneableonly');
+        }
+
         $r->print(&build_filters($filterlist,$type,$roleelement,$multelement,
-                                 $filter,$action,\$numtitles));
+                                 $filter,$action,\$numtitles,undef,$cloneruname,
+                                 $clonerudom));
     }
 
 # ---------------------------------------------------------------- Get the data
-    if (($env{'form.command'} eq 'gosearch') || $onlyown) {
-        my %courses = &search_courses($r,$type,$onlyown,$filter,$numtitles);
+    if ((($env{'form.gosearch'}) && ($env{'form.updater'} eq '')) || 
+         $onlyown) {
+        my %courses = &search_courses($r,$type,$onlyown,$filter,$numtitles,
+                                      $cloneruname,$clonerudom);
         if ($nohost) {
             $r->print ('<span class="LC_warning">'.
                        &mt('User does not exist - username: [_1], domain: [_2].',
                            '<b>'.$filter->{'personfilter'}.'</b>',
                            '<b>'.$filter->{'persondomfilter'}.'</b>').'</span>');
         } else {
-            &display_matched_courses($r,$type,$multiple,$action,$showroles,%courses);
+            &display_matched_courses($r,$type,$multiple,$action,$showroles,$cloneruname,
+                                     $clonerudom,%courses);
         }
     }
     $r->print(&Apache::loncommon::end_page());
     return OK;
 }
 
+sub js_changer {
+    return <<"ENDJS";
+<script type="text/javascript">
+
+function updateFilters(caller) {
+    if (typeof(caller) != "undefined") {
+        document.filterpicker.updater.value = caller.name;
+    }
+    document.filterpicker.submit();
+}
+
+</script>
+
+ENDJS
+
+}
+
 sub processpick {
     my $openerform = 'rolechoice';
     if ($env{'form.form'} eq 'studentform') {
@@ -238,7 +276,7 @@
 }
 
 sub display_matched_courses {
-    my ($r,$type,$multiple,$action,$showroles,%courses) = @_;
+    my ($r,$type,$multiple,$action,$showroles,$cloneruname,$clonerudom,%courses) = @_;
     if ($env{'form.form'} eq 'portform') {
         $action = '/adm/portfolio';
     }
@@ -315,11 +353,26 @@
             my $cleandesc=&HTML::Entities::encode($description,'<>&"');
             $cleandesc=~s/'/\\'/g;
             my ($cdom,$cnum)=split(/\_/,$course);
-            my ($descr,$instcode,$ttype,@owners);
+            my ($descr,$instcode,$ttype,$canclone,@owners);
             if (ref($courses{$course}) eq 'HASH') {
                 $descr = $courses{$course}{'description'};
-                $instcode =  $courses{$course}{'inst_code'};
-                $ttype =  $courses{$course}{'type'};
+                $instcode = $courses{$course}{'inst_code'};
+                $ttype = $courses{$course}{'type'};
+                if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) {
+                    my $cloners = $courses{$course}{'cloners'};
+                    if ($cloners ne '') { 
+                        my @cloneable = split(',',$cloners);
+                        if (grep(/^\*$/,@cloneable)) {
+                            $canclone = 1;
+                        }
+                        if (grep(/^\*:\Q$env{'form.clonerudom'}\E$/,@cloneable)) {
+                            $canclone = 1;
+                        }
+                        if (grep(/^\Q$cloneruname\E:\Q$clonerudom\E$/,@cloneable)) {
+                            $canclone = 1;
+                        }
+                    }
+                }
                 push(@owners,&unescape($courses{$course}{'owner'}));
                 if (ref($courses{$course}{'co-owners'}) eq 'ARRAY') {
                     foreach my $item (@{$courses{$course}{'co-owners'}}) {
@@ -332,7 +385,7 @@
                 push(@owners,&unescape($singleowner));
             }
             my $ownerstr = join(', ',@owners);
-            $r->print('<td>'.&course_chooser($multiple,$cdom,$cnum,$cleandesc).'</td>');
+            $r->print('<td>'.&course_chooser($multiple,$cdom,$cnum,$cleandesc,$canclone).'</td>');
             $r->print('<td>'.$description.'</td>');
             $r->print('<td>');
             $r->print(&Apache::lonnet::domain($cdom,'description')?
@@ -397,7 +450,7 @@
         $r->print('<input type="hidden" name="setroles" value="'.$env{'form.setroles'}.'" />');
         $r->print('<input type="hidden" name="action" value="rolepicker" />');
     } elsif ($env{'form.form'} eq 'modifycourse') {
-        $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','pickedcourse','type','form','numtitles','state','command']));
+        $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','pickedcourse','type','form','numtitles','state']));
     } else {
         $r->print('<input type="hidden" name="cnumelement" value="'.
                   $env{'form.cnumelement'}.'" />'."\n".  
@@ -424,10 +477,9 @@
 
 sub build_filters {
     my ($filterlist,$type,$roleelement,$multelement,$filter,$action,
-        $numtitlesref,$caller) = @_;
-    my $list;
-    my $formname;
-    my ($fixeddom,$codedom,$jscript);
+        $numtitlesref,$caller,$cloneruname,$clonerudom) = @_;
+    my ($list,$formname,$fixeddom,$codedom,$jscript);
+    $codedom = $env{'request.role.domain'};
     if (defined($env{'form.form'})) {
         $formname = $env{'form.form'};
     } else {
@@ -435,7 +487,7 @@
     }
     my $onchange;
     unless ($env{'form.interface'} eq 'textual') {
-        $onchange = 1;
+        $onchange = 'javascript:updateFilters(this)';
     }
     my ($domainselectform,$sincefilterform,$ownerdomselectform,$persondomselectform,
         $instcodeform,$typeselectform,$instcodetitle);
@@ -456,7 +508,7 @@
             } elsif ($item eq 'personfilter') {
                 $filter->{$item} = &LONCAPA::clean_username($filter->{$item});
                 if ($env{'form.persondomfilter'} eq '') {
-                    unless ($env{'form.command'} eq 'gosearch') {
+                    unless ($env{'form.gosearch'}) {
                         $filter->{'persondomfilter'} = $env{'request.role.domain'};
                     }
                 } else {
@@ -529,39 +581,51 @@
 
     $typeselectform =  '<select name="type" size="1"';
     if ($onchange) {
-        $typeselectform .= 'onchange=" javascript:submit()"';
+        $typeselectform .= 'onchange="'.$onchange.'"';
     }
     $typeselectform .= '>'."\n";
-    my $officialjs;
-    if ($type eq 'Course') {
-        if (($env{'form.fixeddom'}) || ($env{'form.form'} eq 'requestcrs')) {
-            $officialjs = 1;
-            ($instcodeform,$jscript,$$numtitlesref) = 
-                &instcode_selectors($codedom,'filterpicker',$officialjs);
-        }
-        if ($instcodeform eq '') {
-            $instcodeform = 
-                '<input type="text" name="instcodefilter" size="10" value="'.
-                $list->{'instcodefilter'}.'" />';
-            $instcodetitle = $lt{'ins'};
+    
+    my ($cloneableonlyform,$cloneabletitle);
+    if (exists($filter->{'cloneableonly'})) {
+        my $cloneableon = '';
+        my $cloneableoff = ' checked="checked"';
+        if ($filter->{'cloneableonly'}) {
+            $cloneableon = $cloneableoff;
+            $cloneableoff = '';
+        }
+        $cloneableonlyform = '<span class="LC_nobreak"><label><input type="radio" name="cloneableonly" value="1" '.$cloneableon.'/>&nbsp;'.&mt('Yes').'</label>'.('&nbsp;'x3).'<label><input type="radio" name="cloneableonly" value="" '.$cloneableoff.' />&nbsp;'.&mt('No').'</label></span>';
+        if ($env{'form.form'} eq 'ccrs') {
+            $cloneabletitle = &mt('Cloneable for').' '.$cloneruname.':'.$clonerudom;
         } else {
-            $instcodetitle = $lt{'inc'};
+            $cloneabletitle = &mt('Cloneable by you');
         }
-        if ($env{'form.fixeddom'}) {
-            $instcodetitle .= '<br />('.$codedom.')';
+    }
+    my $officialjs;
+    if ($type eq 'Course') {
+        if (exists($filter->{'instcodefilter'})) {
+            if (($env{'form.fixeddom'}) || ($formname eq 'requestcrs')
+                || ($formname eq 'modifycourse')) {
+                $officialjs = 1;
+                ($instcodeform,$jscript,$$numtitlesref) = 
+                    &instcode_selectors($codedom,'filterpicker',$officialjs);
+                if ($jscript) {
+                    $jscript = '<script type="text/javascript" language="Javascript">'.
+                               $jscript.'</script>'."\n";
+                }
+            }
+            if ($instcodeform eq '') {
+                $instcodeform = 
+                    '<input type="text" name="instcodefilter" size="10" value="'.
+                    $list->{'instcodefilter'}.'" />';
+                $instcodetitle = $lt{'ins'};
+            } else {
+                $instcodetitle = $lt{'inc'};
+            }
+            if ($env{'form.fixeddom'}) {
+                $instcodetitle .= '<br />('.$codedom.')';
+            }
         }
     }
-    $jscript .= <<"END_JS";
-
-function setCommand() {
-    document.filterpicker.command.value = 'gosearch';
-    return;
-}
-
-END_JS
-
-    $jscript = '<script type="text/javascript" language="Javascript">'.$jscript.
-               '</script>'."\n";
 
     foreach my $posstype ('Course','Community') {
         $typeselectform.='<option value="'.$posstype.'"'.
@@ -569,7 +633,7 @@
     }
     $typeselectform.="</select>";
     my $output = qq|
-<form method="post" name="filterpicker" action="$action" onsubmit="setCommand()">
+<form method="post" name="filterpicker" action="$action">
 <input type="hidden" name="form" value="$formname" />
 |;
     if ($formname eq 'modifycourse') {
@@ -639,17 +703,44 @@
                   .$list->{'coursefilter'}.'" />'
                   .&Apache::lonhtmlcommon::row_closure();
     }
+    if ($cloneableonlyform) {
+        $output .= &Apache::lonhtmlcommon::row_title($cloneabletitle).
+                   $cloneableonlyform.&Apache::lonhtmlcommon::row_closure();
+    }
     if (exists($filter->{'descriptfilter'})) {
         $output .= &Apache::lonhtmlcommon::row_title($lt{'cde'})
                   .'<input type="text" name="descriptfilter" size="40" value="'
                   .$list->{'descriptfilter'}.'" />'
                   .&Apache::lonhtmlcommon::row_closure(1);
     }
-    $output .= &Apache::lonhtmlcommon::end_pick_box();
-    $output .= '<p><input type="hidden" name="command" value="">'."\n".
+    $output .= &Apache::lonhtmlcommon::end_pick_box().'<p>';
+    my $warning;
+    if (($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) {
+        my $cloneruhome=&Apache::lonnet::homeserver($cloneruname,$clonerudom);
+        my $cc_clone;
+        if ($cloneruhome eq 'no_host') {
+            $warning = '<div class="LC_error">'.&mt('Intended course owner does not exist').
+                       '</div>';
+        } else {
+            if ($env{'form.form'} eq 'ccrs') {
+                $output .= '<input type="hidden" name="cloner" value="'.$env{'form.cloner'}.'" />'."\n";
+            }
+            my %ccroles = &Apache::lonnet::get_my_roles($cloneruname,$clonerudom,
+                                                        'userroles',['active'], ['cc']);
+            foreach my $key (sort(keys(%ccroles))) {
+                my ($cnum,$cdom,$role) = split(':',$key);
+                $cc_clone .= $cdom.':'.$cnum.'&';
+            }
+            $cc_clone =~ s/\&$//;
+        }
+        if ($cc_clone ne '') {
+            $output .= '<input type="hidden" name="cc_clone" value="'.$cc_clone.'" />';
+        }
+    }
+    $output .= '<input type="hidden" name="updater" value="">'."\n".
                '<input type="submit" name="gosearch" value="'. 
                &mt('Search').'" /></p>'."\n".'</form>'."\n".'<hr />'."\n";
-    return $jscript.$output;
+    return $jscript.$warning.$output;
 }
 
 sub instcode_selectors {
@@ -680,8 +771,8 @@
 }
 
 sub search_courses {
-    my ($r,$type,$onlyown,$filter,$numtitles) = @_;
-    my (%courses,%showcourses);
+    my ($r,$type,$onlyown,$filter,$numtitles,$cloneruname,$clonerudom) = @_;
+    my (%courses,%showcourses,$cloner);
     if (!$onlyown) {
         $r->print(&mt('Searching ...').'<br />&nbsp;<br />');
         $r->rflush();
@@ -714,6 +805,10 @@
         }
         if ($instcodefilter eq '') { $instcodefilter = '.'; }
         if ($type eq '') { $type = '.'; }
+ 
+        if (($clonerudom ne '') && ($cloneruname ne '')) {
+            $cloner = $cloneruname.':'.$clonerudom;  
+        }
         %courses = 
             &Apache::lonnet::courseiddump($filter->{'domainfilter'},
                                           $filter->{'descriptfilter'},
@@ -721,7 +816,9 @@
                                           $instcodefilter,
                                           $filter->{'combownerfilter'},
                                           $filter->{'coursefilter'},
-                                          undef,undef,$type,$regexpok);
+                                          undef,undef,$type,$regexpok,undef,undef,
+                                          undef,undef,$cloner,$env{'form.cc_clone'},
+                                          $filter->{'cloneableonly'});
         if (($filter->{'personfilter'} ne '') && ($filter->{'persondomfilter'} ne '')) {
             my %rolehash = &Apache::lonnet::get_my_roles($filter->{'personfilter'},
                                                          $filter->{'persondomfilter'},
@@ -757,10 +854,16 @@
 }
 
 sub course_chooser {
-    my ($multiple,$cdom,$cnum,$cleandesc) = @_;
+    my ($multiple,$cdom,$cnum,$cleandesc,$canclone) = @_;
     my $output; 
     if ($multiple) {
         $output = '<label><input type="checkbox" name="course_id" value="'.$cdom.'_'.$cnum.'" />'."\n";
+    } elsif ((($env{'form.form'} eq 'ccrs') || ($env{'form.form'} eq 'requestcrs')) && (!$canclone))  {
+        if ($env{'form.form'} eq 'ccrs') {
+            $output = &mt('No cloning for ').$env{'form.cloner'}."\n";
+        } else {
+            $output = &mt('No rights to clone')."\n";
+        }
     } else {
         $output = '<input type="button" value="'.&mt('Select').'" onClick="gochoose('.
                   "'".$cnum."','".$cdom."','".$cleandesc."')".'" />'."\n";
@@ -957,9 +1060,9 @@
 
 =item *
 X<display_matched_courses()>
-B<display_matched_courses($r,$type,$multiple,$action,$showroles,%courses)>:
+B<display_matched_courses($r,$type,$multiple,$action,$showroles,$cloneruname,$clonerudom,%courses)>:
 
-Input: 7 - request object, course type, multiple (0 or 1), form action, whether to show roles (for course personnel filter), hash of courses.
+Input: 7 - request object, course type, multiple (0 or 1), form action, whether to show roles (for course personnel filter), username of new course owner, domain of new course owner, hash of courses.
 
 Output: 0
 
@@ -978,7 +1081,7 @@
 
 =item *
 X<build_filters()>
-B<build_filters($filterlist,$type,$roleelement,$multelement,$filter,$action,$numfiltersref,$caller)>:
+B<build_filters($filterlist,$type,$roleelement,$multelement,$filter,$action,$numfiltersref,$caller,$cloneruname,$clonerudom)>:
 
 
 Input: 7 - anonymous array of search criteria; course type; $roleelement ; $multelement ; anonymous hash of criteria and their values; form action; ref to scalar (count of number of elements in institutional codes -- e.g., 4 for year, semester, department, and number); caller context (e.g., set to 'modifycourse' when routine is called from lonmodifycourse.pm).
@@ -989,10 +1092,10 @@
 
 =item *
 X<search_courses()>
-B<search_courses($r,$type,$onlyown,$filter,$numtitles)>:
+B<search_courses($r,$type,$onlyown,$filter,$numtitles,$cloneruname,$clonerudom)>:
 
 
-Input: 5 -  request object, course type, search scope: only courses in which user has active role (1), or any course (0); anonymous hash of criteria and their values; for institutional codes - number of categories).  
+Input: 7 -  request object, course type, search scope: only courses in which user has active role (1), or any course (0); anonymous hash of criteria and their values; for institutional codes - number of categories; optional username of new course owner, optional domain of new course owner). Last two needed when search is for courses to clone from course request form, or course creation form (DC).   
 
 Output: 1 - %courses - hash of courses satisfying search criteria, keys = course IDs, values are corresponding colon-separated escaped description, institutional code, owner and type.
 
@@ -1001,11 +1104,11 @@
 
 =item *
 X<course_chooser()>
-B<course_chooser($multiple,$cdom,$cnum,$cleandesc)>:
+B<course_chooser($multiple,$cdom,$cnum,$cleandesc,$canclone)>:
 
-Input: 4 - single (0) or multiple (1) courses; course domain, course number; course description. 
+Input: 5 - single (0) or multiple (1) courses; course domain, course number; course description; can clone course (1 if new course owner has cloning rights). 
 
-Output: 1 - HTML for either checkbox (multiple=1) or select button (multiple=0) for user yo indicate course selection.
+Output: 1 - HTML for either checkbox (multiple=1) or select button (multiple=0) for user to indicate course selection.
 
 Side Effects: None
 

--raeburn1249009291--