--- rat/lonwrapper.pm 2022/01/02 15:37:30 1.49.2.11.2.1 +++ rat/lonwrapper.pm 2022/08/30 11:48:33 1.49.2.11.2.2 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Wrapper for external and binary files as standalone resources # -# $Id: lonwrapper.pm,v 1.49.2.11.2.1 2022/01/02 15:37:30 raeburn Exp $ +# $Id: lonwrapper.pm,v 1.49.2.11.2.2 2022/08/30 11:48:33 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -38,13 +38,15 @@ use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::lonextresedit(); use Apache::lonexttool(); +use Apache::lonnavmaps(); use LONCAPA qw(:DEFAULT :match); use HTML::Entities(); +use Digest::MD5(); # ================================================================ Main Handler sub wrapper { my ($r,$url,$brcrum,$absolute,$is_ext,$is_pdf,$exttool,$linktext,$explanation, - $title,$width,$height) = @_; + $title,$width,$height,$reuse) = @_; my $forcereg; unless ($env{'form.folderpath'}) { @@ -69,7 +71,10 @@ sub wrapper { } elsif ($env{'form.anchor'} ne '') { $anchor = '#'.$env{'form.anchor'}; } - unless (($is_pdf) && ($clientmobile)) { + if (($is_ext eq 'tab') || ($is_ext eq 'window')) { + $uselink = 1; + } + unless (($is_pdf && $clientmobile) || $uselink) { my $hostname = $r->hostname(); my $lonhost = $r->dir_config('lonHostID'); my $ip = &Apache::lonnet::get_host_ip($lonhost); @@ -124,22 +129,79 @@ var LCresizedef = 0; } } } - if ($clientmobile || ($exttool eq 'window') || ($exttool eq 'tab')) { + if ($clientmobile || ($exttool eq 'window') || ($exttool eq 'tab') || + ($is_ext eq 'tab') || ($is_ext eq 'window')) { my $output = $startpage; if ($is_pdf) { $linktext = &mt('Link to PDF (for mobile devices)'); $output .= &create_link($url,$anchor,$title,$linktext); - } elsif (($exttool eq 'window') || ($exttool eq 'tab')) { + } elsif (($exttool eq 'window') || ($exttool eq 'tab') || + ($is_ext eq 'tab') || ($is_ext eq 'window')) { + my $preamble; if ($linktext eq '') { - $linktext = &mt('Launch External Tool'); + if ($exttool) { + $linktext = &mt('Launch External Tool'); + } else { + $linktext = &mt('Link to External Resource'); + } + } + if ($exttool) { + $url = &HTML::Entities::encode($url,'"<>&'); + } else { + $url = &HTML::Entities::encode($url.$anchor,'&<>"'); } - $url = &HTML::Entities::encode($url,'"<>&'); - if ($exttool eq 'tab') { - $output .= '
'. - ''. + if (($exttool eq 'tab') || ($is_ext eq 'tab')) { + my $target; + if ($exttool) { + $target = 'LCExternalToolTab'; + } else { + if ($reuse) { + $target = 'LCExternalResTab'; + } else { + $target = '_blank'; + } + if ($title ne '') { + $preamble = ''.$title.'
'; + } + } + $output .= '
'.$preamble. + ''. $linktext.''. '
'; } else { + my ($target,$extlinkimg); + if ($exttool) { + $target = 'LCExternalToolPopUp'; + } else { + $target = 'LCExternalResPopUp'; + if ($title ne '') { + $preamble = ''.$title.'
'; + } + $extlinkimg = ''; + unless ($reuse) { + my $resid; + if ($env{'request.course.id'}) { + unless ($env{'form.folderpath'} =~ /^supplemental/) { + my $symb=&Apache::lonnet::symbread($r->uri); + if ($symb) { + my $navmap = Apache::lonnavmaps::navmap->new(); + if (ref($navmap)) { + my $res = $navmap->getBySymb($symb); + if (ref($res)) { + $resid = $res->id; + $resid =~ s/\./_/g; + } + } + } + } + } + if ($resid eq '') { + $resid = substr(Digest::MD5::md5_hex(Digest::MD5::md5_hex(time(). {}. rand(). $$)), 0, 8); + } + &js_escape(\$resid); + $target .= $resid; + } + } $output .= <<"ENDLINK"; -
- -$linktext +
$preamble + +$linktext$extlinkimg
ENDLINK } - if ($explanation ne '') { - $output .= '
'.$explanation.'
'; + if ($exttool) { + if ($explanation ne '') { + $output .= '
'.$explanation.'
'; + } } } else { if ($uselink) { @@ -273,7 +337,7 @@ sub handler { my $url = $r->uri; my ($is_ext,$brcrum,$absolute,$is_pdf,$exttool,$cdom,$cnum,$hostname, - $linktext,$explanation,$width,$height); + $linktext,$explanation,$width,$height,$reuse); for ($url){ s|^/adm/wrapper||; @@ -284,6 +348,27 @@ sub handler { if ($url =~ /\.pdf$/i) { $is_pdf = 1; + } elsif (($is_ext) && ($env{'request.course.id'})) { + if ($env{'course.'.$env{'request.course.id'}.'.extresource'}) { + (my $selected,$reuse,$width,$height) = split(/:/,$env{'course.'.$env{'request.course.id'}.'.extresource'}); + if ($selected eq 'tab') { + $is_ext = 'tab'; + $width = ''; + $height = ''; + } elsif ($selected eq 'window') { + $is_ext = 'window'; + unless ($width =~ /^\d+$/) { + $width = ''; + } + unless ($height =~ /^\d+$/) { + $height = ''; + } + } else { + $width = ''; + $height = ''; + $reuse = ''; + } + } } elsif ($url =~ m{^/adm/($match_domain)/($match_courseid)/(\d+)/ext\.tool$}) { $cdom = $1; $cnum = $2; @@ -385,7 +470,7 @@ sub handler { } $r->print( wrapper($r,$url,$brcrum,$absolute,$is_ext,$is_pdf,$exttool, - $linktext,$explanation,undef,$width,$height) ); + $linktext,$explanation,undef,$width,$height,$reuse) ); } # not just the menu @@ -412,7 +497,7 @@ described at http://www.lon-capa.org. =over -=item wrapper($r,$url,$brcrum,$absolute,$is_ext,$is_pdf,$exttool,$linktext,$explanation,$title,$width,$height) +=item wrapper($r,$url,$brcrum,$absolute,$is_ext,$is_pdf,$exttool,$linktext,$explanation,$title,$width,$height,$reuse) =over @@ -422,8 +507,11 @@ request object =item $url -url to display by including in an iframe within a -LON-CAPA page which has a standard LON-CAPA inline menu. +url to display either by including in an iframe within a +LON-CAPA page which has a standard LON-CAPA inline menu, +or in some cases launched in a separate tab or window, +launched via a link in a LON-CAPA page with standard inline +menu. =item $brcrum @@ -452,12 +540,32 @@ in Firefox 23 and later, when serving fr =item $is_ext -true if URL is for an external resource. +true if URL is for an external resource. Default true value +is 1 (display in iframe, unless $uselink is true). +If external resource is to be displayed in a tab, +value of $is_ext will be tab, if to be displayed in a pop-up window, +value of $is_ext will be window. =item $is_pdf true if URL is for a PDF (based on file extension). +=item $exttool + +If URL is for an External Tool, will contain the target type: iframe, window or tab. + +=item $linktext + +optional. If URL is for an External Tool, and target type is window or tab, +then the link text may be an option set in the course for each tool instance, +or may be a default defined in the domain for all instances of the tool. + +=item $explanation + +optional. If URL is for an External Tool, and target type is window or tab, +then the explanation is an option set in the course for each tool instance, +or may be a default defined in the domain for all instances of the tool. + =item $title optional. If wrapped item is a PDF, and $clientmobile is true, @@ -466,12 +574,55 @@ above the link, but if not provided as a will be used, otherwise, the filename will be displayed (unless hidden URL set for the resource). +=item $width + +optional. If URL is for an External Tool, and target type is window, +then a default width may have been defined in the domain for all instances of +the tool. If so, that width will be used for the window opened (via a link) +to launch the external tool. If the URL is for an External Resource, and +$is_ext is window, then a default width (px) may have been defined in the current +course for all external resource instances. + +=item $height + +optional. If URL is for an External Tool, and target type is window, +then a default height may have been defined in the domain for all instances of +the tool. If so, that height will be used for the window opened (via a link) +to launch the external tool. If the URL is for an External Resource, and +$is_ext is window, then a default height (px) may have been defined in the current +course for all external resource instances. + +=item $reuse + +optional. If the URL is for an External Resource, and $is_ext is tab or window, +then $reuse will be true if the same tab or window is to be reused for display +of all external resource instances in a a course. + =back Returns markup for the entire page. =item handler() +Content handler for requests for: /adm/wrapper/... +used for content to be displayed in an iframe, or launched in a separate tab +or window via a link. The target URL is extracted from the requested URL, by +removing the /adm/wrapper prefix. + +The target URL will typically be a PDF served from the current server, an +external resource URL served from a different server, or an external tool +(from an LTI Provider) launched from LON-CAPA (as LTI Consumer) and launched +via a link. + +If the request included forceedit in the query string, and the requester has +rights to modify course content, then the editor will be displayed to allow +changes to be made to the resource (e.g., change the URL of the external resource, +or change the setting for the external tool instance). + +If not in edit mode, then the wrapper() subroutine will be called to generate the +standard LON-CAPA inline menu, and then either a link to launch a separate tab or +window, or an iframe to display the content inline. + =back =cut