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

raeburn raeburn at source.lon-capa.org
Thu Jul 20 18:12:39 EDT 2023


raeburn		Thu Jul 20 22:12:39 2023 EDT

  Modified files:              
    /loncom/interface	londocs.pm 
  Log:
  - External Tool instances can be copied between courses in the same domain
    via the Course Editor Clipboard. For tools defined within a course, the
    tool definition (including tool and secret) will be copied to the new course,
    as long as the session-hosting server belongs to the course's homeserver
    institution.
  
  
-------------- next part --------------
Index: loncom/interface/londocs.pm
diff -u loncom/interface/londocs.pm:1.703 loncom/interface/londocs.pm:1.704
--- loncom/interface/londocs.pm:1.703	Sun Jul 16 03:50:54 2023
+++ loncom/interface/londocs.pm	Thu Jul 20 22:12:39 2023
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Documents
 #
-# $Id: londocs.pm,v 1.703 2023/07/16 03:50:54 raeburn Exp $
+# $Id: londocs.pm,v 1.704 2023/07/20 22:12:39 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1419,7 +1419,7 @@
     }
 
     my @currpaste = split(/,/,$env{'docs.markedcopies'});
-    my ($pasteitems, at pasteable);
+    my ($pasteitems, at pasteable,$same_institution,$checkedsameinst);
     my $clipboardcount = 0;
 
 # Construct identifiers for current contents of user's paste buffer
@@ -1432,11 +1432,13 @@
             ($url ne '')) {
             $clipboardcount ++;
             my ($is_external,$othercourse,$fromsupp,$is_uploaded_map,$parent,
-                $canpaste,$nopaste,$othercrs,$areachange,$is_exttool);
+                $canpaste,$nopaste,$othercrs,$areachange,$is_exttool,$toolcdom,
+                $toolcnum,$marker);
             my $extension = (split(/\./,$env{'docs.markedcopy_url_'.$suffix}))[-1];
             if ($url =~ m{^(?:/adm/wrapper/ext|(?:http|https)(?::|:))//} ) {
                 $is_external = 1;
-            } elsif ($url =~ m{^/adm/$match_domain/$match_courseid/\d+/ext\.tool$}) {
+            } elsif ($url =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/ext\.tool$}) {
+                ($toolcdom,$toolcnum,$marker) = ($1,$2,$3);
                 $is_exttool = 1;
             }
             if ($folder =~ /^supplemental/) {
@@ -1474,11 +1476,42 @@
                     if ($cid ne $env{'request.course.id'}) {
                         my ($srcdom,$srcnum) = split(/_/,$cid);
                         if ($env{"user.priv.cm./$srcdom/$srcnum"} =~ /\Q:mdc&F\E/) {
-                            if (($is_exttool) && ($srcdom ne $coursedom)) {
-                                $canpaste = 0;
-                                $nopaste = &mt('Paste from another domain unavailable.');
-                            } else {
-                                $othercrs = '<br />'.&mt('(from another course)');
+                            if ($is_exttool) {
+                                if ($toolcdom ne $coursedom) {
+                                    $canpaste = 0;
+                                    $nopaste = &mt('Paste from another domain unavailable.');
+                                } elsif ($toolcnum ne $coursenum) {
+                                    my %toolsettings =
+                                        &Apache::lonnet::dump('exttool_'.$marker,$toolcdom,$toolcnum);
+                                    my %tooltypes = &Apache::loncommon::usable_exttools();
+                                    if ((($toolsettings{'id'} =~ /^c\d+$/) && (!$tooltypes{'crs'})) ||
+                                        (($toolsettings{'id'} =~ /^\d+$/) && (!$tooltypes{'dom'}))) {
+                                        $canpaste = 0;
+                                        $nopaste = &mt('Paste from another course unavailable.');
+                                    } elsif ($toolsettings{'id'} =~ /^c\d+$/) {
+                                        unless ($checkedsameinst) {
+                                            my $primary_id = &Apache::lonnet::domain($coursedom,'primary');
+                                            my $intdom = &Apache::lonnet::internet_dom($primary_id);
+                                            if ($intdom ne '') {
+                                                my $internet_names =
+                                                    &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});
+                                                if (ref($internet_names) eq 'ARRAY') {
+                                                    if (grep(/^\Q$intdom\E$/,@{$internet_names})) {
+                                                        $same_institution = 1;
+                                                    }
+                                                }
+                                            }
+                                            $checkedsameinst = 1;
+                                        }
+                                        if ($same_institution) {
+                                            $othercrs = '<br />'.&mt('(from another course)');
+                                        } else {
+                                            $nopaste = &mt('Paste from another course unavailable.');
+                                        }
+                                    } else {
+                                        $othercrs = '<br />'.&mt('(from another course)');
+                                    }
+                                }
                             }
                         } else {
                             $canpaste = 0;
@@ -1785,9 +1818,12 @@
         return();
     }
 
-    my (%msgs,%before,%after, at dopaste,%is_map,%notinsupp,%notincrs,%notindom,%duplicate,
-        %prefixchg,%srcdom,%srcnum,%srcmapidx,%marktomove,$save_err,$lockerrors,$allresult);
-
+    my (%msgs,%before,%after, at dopaste,%is_map,%notinsupp,%notincrs,%notindom,
+        %othcrstool,%othcrsres,%duplicate,%prefixchg,%srcdom,%srcnum,%srcmapidx,
+        %marktomove,$save_err,$lockerrors,$allresult,%currcrsltitools,
+        %currltititles,$currltimax,$gotcrsltitools);
+    $currltimax = 0;
+    $gotcrsltitools = 0;
     foreach my $suffix (@topaste) {
         my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url_'.$suffix});
         my $cid=&LONCAPA::map::qtescape($env{'docs.markedcopy_crs_'.$suffix});
@@ -1826,10 +1862,40 @@
                 }
             }
 # When buffer was populated using an active role in a different course
-# disallow pasting of External Tool if course is in a different domain.
-            if (($url =~ m{/ext\.tool$}) && ($srcd ne $coursedom)) {
-                $notindom{$suffix} = 1;
-                next;
+# disallow pasting of External Tool if course is in a different domain,
+# or if External Tool use is not permitted in this course.
+            if ($url =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/ext\.tool$}) {
+                my ($toolcdom,$toolcnum,$marker) = ($1,$2,$3);
+                if ($toolcdom ne $coursedom) {
+                    $notindom{$suffix} = 1;
+                    next;
+                } elsif ($toolcnum ne $coursenum) {
+                    my %toolsettings =
+                        &Apache::lonnet::dump('exttool_'.$marker,$toolcdom,$toolcnum);
+                    my %tooltypes = &Apache::loncommon::usable_exttools();
+                    if ((($toolsettings{'id'} =~ /^c\d+$/) && (!$tooltypes{'crs'})) ||
+                        (($toolsettings{'id'} =~ /^\d+$/) && (!$tooltypes{'dom'}))) {
+                        $othcrstool{$suffix} = 1;
+                        next;
+                    }
+                    if ($toolsettings{'id'} =~ /^c\d+$/) {
+                        unless ($gotcrsltitools) {
+                            %currcrsltitools =
+                                &Apache::lonnet::get_course_lti($coursenum,$coursedom,'consumer');
+                            foreach my $item (sort(keys(%currcrsltitools))) {
+                                if (ref($currcrsltitools{$item}) eq 'HASH') {
+                                    $currltimax ++;
+                                    if (ref($currltititles{$currcrsltitools{$item}{'title'}}) eq 'ARRAY') {
+                                        push(@{$currltititles{$currcrsltitools{$item}{'title'}}},$item);
+                                    } else {
+                                        $currltititles{$currcrsltitools{$item}{'title'}} = [$item];
+                                    }
+                                }
+                            }
+                            $gotcrsltitools = 1;
+                        }
+                    }
+                }
             }
             $srcdom{$suffix} = $srcd;
             $srcnum{$suffix} = $srcn;
@@ -1894,6 +1960,7 @@
                 notinsupp => 'Paste failed: content type is not supported within Supplemental Content',
                 notincrs  => 'Paste failed: Item is from a different course which you do not have rights to edit.',
                 notindom  => 'Paste failed: Item is an external tool from a course in a different domain.',
+                othcrstool => 'Paste failed: Item is an external tool from a different course, for which use is not allowed in this course.',
                 othcrsres => 'Paste failed: Item is a course-authored resource from a different course',
                 duplicate => 'Paste failed: only one instance of a particular published sequence or page is allowed within each course.',
             );
@@ -1923,7 +1990,9 @@
 # Retrieve information about all course maps in main content area 
 
     my $allmaps = {};
-    my (@toclear,%mapurls,%lockerrs,%msgerrs,%results,$donechk);
+    my (@toclear,%mapurls,%lockerrs,%msgerrs,%results,$donechk,
+        @updatetoolsenc,$updatetoolscache,$checkedsameinst,
+        $same_institution);
 
 # Loop over the items to paste
     foreach my $suffix (@dopaste) {
@@ -2022,12 +2091,27 @@
                     $fromothercrs = 1;
                     $info{'cdom'} = $srcdom{$suffix};
                     $info{'cnum'} = $srcnum{$suffix};
+                    unless ($checkedsameinst) {
+                        my $primary_id = &Apache::lonnet::domain($coursedom,'primary');
+                        my $intdom = &Apache::lonnet::internet_dom($primary_id);
+                        if ($intdom ne '') {
+                            my $internet_names =
+                                &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});
+                            if (ref($internet_names) eq 'ARRAY') {
+                                if (grep(/^\Q$intdom\E$/,@{$internet_names})) {
+                                    $same_institution = 1;
+                                }
+                            }
+                        }
+                        $checkedsameinst = 1;
+                    }
                 }
             }
             unless (($env{'form.docs.markedcopy_options_'.$suffix} eq 'move') && (!$fromothercrs)) {
                 my (%lockerr,$msg);
                 my ($newurl,$result,$errtext) =
-                    &dbcopy(\%info,$coursedom,$coursenum,\%lockerr);
+                    &dbcopy(\%info,$coursedom,$coursenum,\%lockerr,\%currltititles,
+                            \$currltimax,\@updatetoolsenc,\$updatetoolscache,$same_institution);
                 if ($result eq 'ok') {
                     $url = $newurl;
                     $title=&mt('Copy of').' '.$title;
@@ -2196,6 +2280,10 @@
             }
         }
     }
+    if (($updatetoolscache) || (@updatetoolsenc)) {
+        &update_ltitools_caches($coursedom,$coursenum,$updatetoolscache,
+                                \@updatetoolsenc);
+    }
     &clear_from_buffer(\@toclear,\@currpaste);
     my $msgsarray;
     foreach my $suffix (keys(%msgs)) {
@@ -2244,6 +2332,30 @@
     return $numdel;
 }
 
+sub update_ltitools_caches {
+    my ($coursedom,$coursenum,$updatetoolscache,$updatetoolsenc) = @_;
+    my $hashid=$coursedom.'_'.$coursenum;
+    if ($updatetoolscache) {
+        &Apache::lonnet::devalidate_cache_new('courseltitools',$hashid);
+    }
+    if ((ref($updatetoolsenc) eq 'ARRAY') &&
+        (@{$updatetoolsenc})) {
+        my @ids=&Apache::lonnet::current_machine_ids();
+        my $updatedone;
+        foreach my $lonhost (@{$updatetoolsenc}) {
+            if (grep(/^\Q$lonhost\E$/, at ids)) {
+                unless ($updatedone) {
+                    &Apache::lonnet::devalidate_cache_new('crsltitoolsenc',$hashid);
+                }
+                $updatedone = 1;
+            } else {
+                &Apache::lonnet::remote_devalidate_cache($lonhost,["crsltitoolsenc:$hashid"]);
+            }
+        }
+    }
+    return;
+}
+
 sub get_newmap_url {
     my ($url,$folder,$prefixchg,$coursedom,$coursenum,$srcdom,$srcnum,
         $titleref,$allmaps,$newurls) = @_;
@@ -2305,7 +2417,8 @@
 }
 
 sub dbcopy {
-    my ($dbref,$coursedom,$coursenum,$lockerrorsref) = @_;
+    my ($dbref,$coursedom,$coursenum,$lockerrorsref,$currltititles,
+        $currltimax,$updatetoolsenc,$updatetoolscache,$same_institution) = @_;
     my ($url,$result,$errtext);
     if (ref($dbref) eq 'HASH') {
         $url = $dbref->{'src'};
@@ -2349,6 +2462,117 @@
                     my %contents=&Apache::lonnet::dump($db_name,
                                                        $dbref->{'cdom'},
                                                        $dbref->{'cnum'});
+                    my ($toolcopyerror,$toolpassback,$toolroster,%toolinfo,$oldtoolid,$defincrs);
+                    if ($url eq '/adm/'.$dbref->{'cdom'}.'/'.$dbref->{'cnum'}."/$marker/ext.tool") {
+                        if ($contents{'id'} =~ /^(|c)(\d+)$/) {
+                            $oldtoolid = $2;
+                            if ($1 eq 'c') {
+                                $defincrs = 1;
+                                %toolinfo =
+                                    &Apache::lonnet::get('ltitools',[$oldtoolid],$dbref->{'cdom'},$dbref->{'cnum'});
+                            } else {
+                                %toolinfo= &Apache::lonnet::get_domain_lti($dbref->{'cdom'},'consumer');
+                            }
+                            if (ref($toolinfo{$oldtoolid}) eq 'HASH') {
+                                if ($toolinfo{$oldtoolid}{'passback'}) {
+                                    $toolpassback = 1;
+                                }
+                                if ($toolinfo{$oldtoolid}{'roster'}) {
+                                    $toolroster = 1;
+                                }
+                            } else {
+                                $toolcopyerror = 1;
+                                $errtext = &mt('Could not retrieve original settings for pasted external tool.');
+                            }
+                        }
+                        unless (($dbref->{'cnum'} eq $coursenum) && ($dbref->{'cdom'} eq $coursedom)) {
+                            $url = "/adm/$coursedom/$coursenum/$marker/ext.tool";
+                            if ($contents{'crstitle'} ne '') {
+                                $contents{'crstitle'} = $env{'course.'.$coursedom.'_'.$coursenum.'.description'};
+                            }
+                            if (($defincrs) && (!$toolcopyerror)) {
+                                my %newtool;
+                                my $oldcdom = $dbref->{'cdom'};
+                                my $oldcnum = $dbref->{'cnum'};
+                                my $title = $toolinfo{$oldtoolid}{'title'};
+                                if (ref($currltititles) eq 'HASH') {
+                                    if (exists($currltititles->{$title})) {
+                                        $title .= ' (copied from another course)';
+                                    }
+                                }
+                                my ($newid,$iderror) =
+                                    &Apache::lonnet::get_ltitools_id('course',$coursedom,$coursenum,$title);
+                                if ($newid =~ /^\d+$/) {
+                                    %{$newtool{$newid}} = %{$toolinfo{$oldtoolid}};
+                                    $newtool{$newid}{'title'} = $title;
+                                    if (ref($currltimax)) {
+                                        $newtool{$newid}{'order'} = $$currltimax;
+                                    }
+                                    if ($newtool{$newid}{'image'} =~ m{^\Q/uploaded/$oldcdom/$oldcnum/toollogo/$oldtoolid/\E([^/]+)$}) {
+                                        my $fname = $1;
+                                        my $content = &Apache::lonnet::getfile($newtool{$newid}{'image'});
+                                        if ($content eq '-1') {
+                                            delete($newtool{$newid}{'image'});
+                                        } else {
+                                            $env{'form.'.$suffix.'.image'} = $content;
+                                            my $newlogo =
+                                                &Apache::lonnet::finishuserfileupload($coursenum,$coursedom,$suffix.'.image',"toollogo/$newid/$fname");
+                                            delete($env{'form.'.$suffix.'.image'});
+                                            if ($newlogo =~ m{^/uploaded/}) {
+                                                $newtool{$newid}{'image'} = $newlogo;
+                                            } else {
+                                                delete($newtool{$newid}{'image'});
+                                            }
+                                        }
+                                    }
+                                    my $newusable;
+                                    if ($same_institution) {
+                                        my %oldtoolsenc = &Apache::lonnet::eget('nohist_toolsenc',[$oldtoolid],$oldcdom,$oldcnum);
+                                        if (ref($oldtoolsenc{$oldtoolid}) eq 'HASH') {
+                                            my %newtoolsenc;
+                                            %{$newtoolsenc{$newid}} = %{$oldtoolsenc{$oldtoolid}};
+                                            my $putres = &Apache::lonnet::put('nohist_toolsenc',\%newtoolsenc,$coursedom,$coursenum,1);
+                                            if ($putres eq 'ok') {
+                                                if (ref($updatetoolsenc) eq 'ARRAY') {
+                                                    my $newhome = &Apache::lonnet::homeserver($coursenum,$coursedom);
+                                                    unless (grep(/^\Q$newhome\E$/,@{$updatetoolsenc})) {
+                                                        push(@{$updatetoolsenc},$newhome);
+                                                    }
+                                                }
+                                                $newusable = 1;
+                                            }
+                                        }
+                                    }
+                                    if ($newtool{$newid}{'usable'}) {
+                                        unless ($newusable) {
+                                            delete($newtool{$newid}{'usable'});
+                                        }
+                                    }
+                                    my $putres = &Apache::lonnet::put('ltitools',\%newtool,$coursedom,$coursenum);
+                                    if ($putres eq 'ok') {
+                                        $contents{'id'} = "c$newid";
+                                        if (ref($updatetoolscache)) {
+                                            $$updatetoolscache ++;
+                                        }
+                                        if (ref($currltititles->{$title}) eq 'ARRAY') {
+                                            push(@{$currltititles->{$title}},$newid);
+                                        } else {
+                                            $currltititles->{$title} = [$newid];
+                                        }
+                                        if (ref($currltimax)) {
+                                            $$currltimax ++;
+                                        }
+                                    } else {
+                                        $toolcopyerror = 1;
+                                        $errtext = &mt('Unable to save external tool definition in Course Settings.');
+                                    }
+                                } else {
+                                    $toolcopyerror = 1;
+                                    $errtext = &mt('Unable to retrieve new tool ID when adding external tool definition to Course Settings.');
+                                }
+                            }
+                        }
+                    }
                     if (exists($contents{'uploaded.photourl'})) {
                         my $photo = $contents{'uploaded.photourl'};
                         my ($subdir,$fname) =
@@ -2368,13 +2592,40 @@
                         }
                     }
                     $db_name =~ s{_\d*$ }{_$suffix}x;
-                    if (($prefix eq 'exttool') && ($dbref->{'delgradable'}) && ($contents{'gradable'})) {
-                        delete($contents{'gradable'});
+                    if ($prefix eq 'exttool') {
+                        unless ($toolcopyerror) {
+                            foreach my $key ('oldgradesecret','gradesecret','gradesecretdate','oldrostersecret','rostersecret','rostersecretdate') {
+                                if (exists($contents{$key})) {
+                                    delete($contents{$key});
+                                }
+                            }
+                            if ($dbref->{'delgradable'}) {
+                                if (exists($contents{'gradable'})) {
+                                    delete($contents{'gradable'});
+                                }
+                            }
+                            if ($toolpassback) {
+                                if ($contents{'gradable'}) {
+                                    my $gradesecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
+                                    $contents{'gradesecret'} = $gradesecret;
+                                    $contents{'gradesecretdate'} = time;
+                                }
+                            }
+                            if ($toolroster) {
+                                my $rostersecret = UUID::Tiny::create_uuid_as_string(UUID_V4);
+                                $contents{'rostersecret'} = $rostersecret;
+                                $contents{'rostersecretdate'} = time;
+                            }
+                        }
                     }
-                    $result=&Apache::lonnet::put($db_name,\%contents,
-                                                 $coursedom,$coursenum);
-                    if ($result eq 'ok') {
-                        $url =~ s{/(\d*)/(smppg|bulletinboard|ext\.tool)$}{/$suffix/$2}x;
+                    if (($prefix eq 'exttool') && ($toolcopyerror)) {
+                        $result = 'error';
+                    } else {
+                        $result=&Apache::lonnet::put($db_name,\%contents,
+                                                     $coursedom,$coursenum);
+                        if ($result eq 'ok') {
+                            $url =~ s{/(\d*)/(smppg|bulletinboard|ext\.tool)$}{/$suffix/$2}x;
+                        }
                     }
                 }
                 if (($freedlock ne 'ok') && (ref($lockerrorsref) eq 'HASH')) {
@@ -2529,12 +2780,22 @@
             if ($token->[1] eq 'resource') {
                 next if ($token->[2]->{'type'} eq 'zombie');
                 my $ressrc = $token->[2]->{'src'};
-                if ($ressrc =~ m{^/adm/($match_domain)/$match_courseid/\d+/ext\.tool$}) {
-                    my $srcdom = $1;
+                if ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/ext\.tool$}) {
+                    my ($srcdom,$srcnum,$marker) = ($1,$2,$3);
                     unless ($srcdom eq $coursedom) {
                         $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
                         next;
                     }
+                    unless ($srcnum eq $coursenum) {
+                        my %toolsettings =
+                            &Apache::lonnet::dump('exttool_'.$marker,$srcdom,$srcnum);
+                        my %tooltypes = &Apache::loncommon::usable_exttools();
+                        if ((($toolsettings{'id'} =~ /^c\d+$/) && (!$tooltypes{'crs'})) ||
+                            (($toolsettings{'id'} =~ /^\d+$/) && (!$tooltypes{'dom'}))) {
+                            $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
+                            next;
+                        }
+                    }
                 } elsif ($folder =~ /^supplemental/) {
                     unless (&supp_pasteable($ressrc)) {
                         $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc;
@@ -2744,7 +3005,9 @@
         $oldurl,$url,$caller) = @_;
     my (%rewrites,%zombies,%removefrommap,%removeparam,%dbcopies,%retitles,
         %params,%newsubdir,%before,%after,%copies,%docmoves,%mapmoves, at msgs,
-        %resdatacopy,%lockerrors,$lockmsg);
+        %resdatacopy,%lockerrors,$lockmsg,%currcrsltitools,$gotcrsltitools,
+        %currltititles,$currltimax);
+    $currltimax = 0;
     if (ref($updated) eq 'HASH') {
         if (ref($updated->{'rewrites'}) eq 'HASH') {
             %rewrites = %{$updated->{'rewrites'}};
@@ -2895,6 +3158,7 @@
                 }
             }
         }
+        my ($updatetoolscache, at updatetoolsenc,$same_institution,$checkedsameinst);
         foreach my $key (keys(%updates)) {
             my (%torewrite,%toretitle,%toremove,%remparam,%currparam,%zombie,%newdb);
             if (ref($rewrites{$key}) eq 'HASH') {
@@ -2915,10 +3179,63 @@
             if (ref($dbcopies{$key}) eq 'HASH') {
                 foreach my $idx (keys(%{$dbcopies{$key}})) {
                     if (ref($dbcopies{$key}{$idx}) eq 'HASH') {
+                        my $oldurl = $dbcopies{$key}{$idx}{'src'};
+                        my $oldcdom = $dbcopies{$key}{$idx}{'cdom'};
+                        my $oldcnum = $dbcopies{$key}{$idx}{'cnum'};
+                        my $oldmarker;
+                        if ($oldurl =~ m{^\Q/adm/$oldcdom/$oldcnum/\E(\d+)/ext\.tool$}) {
+                            $oldmarker = $1;
+                            unless (($gotcrsltitools) ||
+                                    (($oldcnum eq $cnum) && ($oldcdom eq $cdom))) {
+                                my %oldtoolsettings=&Apache::lonnet::dump('exttool_'.$oldmarker,$oldcdom,$oldcnum);
+                                if ($oldtoolsettings{'id'} =~ /^c\d+$/) {
+                                    unless ($gotcrsltitools) {
+                                        %currcrsltitools =
+                                            &Apache::lonnet::get_course_lti($cnum,$cdom,'consumer');
+                                        foreach my $item (sort(keys(%currcrsltitools))) {
+                                            if (ref($currcrsltitools{$item}) eq 'HASH') {
+                                                $currltimax ++;
+                                                if (ref($currltititles{$currcrsltitools{$item}{'title'}}) eq 'ARRAY') {
+                                                    push(@{$currltititles{$currcrsltitools{$item}{'title'}}},$item);
+                                                } else {
+                                                    $currltititles{$currcrsltitools{$item}{'title'}} = [$item];
+                                                }
+                                            }
+                                        }
+                                        $gotcrsltitools = 1;
+                                    }
+                                    unless ($checkedsameinst) {
+                                        my $primary_id = &Apache::lonnet::domain($cdom,'primary');
+                                        my $intdom = &Apache::lonnet::internet_dom($primary_id);
+                                        if ($intdom ne '') {
+                                            my $internet_names =
+                                                &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});
+                                            if (ref($internet_names) eq 'ARRAY') {
+                                                if (grep(/^\Q$intdom\E$/,@{$internet_names})) {
+                                                    $same_institution = 1;
+                                                }
+                                            }
+                                        }
+                                        $checkedsameinst = 1;
+                                    }
+                                }
+                            }
+                        }
                         my ($newurl,$result,$errtext) =
-                            &dbcopy($dbcopies{$key}{$idx},$cdom,$cnum,\%lockerrors);
+                            &dbcopy($dbcopies{$key}{$idx},$cdom,$cnum,\%lockerrors,\%currltititles,
+                                    \$currltimax,\@updatetoolsenc,\$updatetoolscache,$same_institution);
                         if ($result eq 'ok') {
                             $newdb{$idx} = $newurl;
+                            if ($newurl =~ /ext\.tool$/) {
+                                if ($torewrite{$idx} eq "/adm/$oldcdom/$oldcnum/$oldmarker/ext.tool") {
+                                    if ($newurl =~ m{^\Q/adm/$cdom/$cnum/\E(\d+)/ext.tool$}) {
+                                        my $newmarker = $1;
+                                        unless ($oldmarker eq $newmarker) {
+                                            $torewrite{$idx} = "/adm/$oldcdom/$oldcnum/$newmarker/ext.tool";
+                                        }
+                                    }
+                                }
+                            }
                         } elsif (ref($errors) eq 'HASH') {
                             $errors->{$key} = 1;
                         }
@@ -3057,6 +3374,10 @@
                 }
             }
         }
+        if (($updatetoolscache) || (@updatetoolsenc)) {
+            &update_ltitools_caches($cdom,$cnum,$updatetoolscache,
+                                    \@updatetoolsenc);
+        }
     }
     return ('ok',\@msgs,$lockmsg);
 }


More information about the LON-CAPA-cvs mailing list