# The LearningOnline Network with CAPA
# Edit Handler for RAT Maps
#
# $Id: lonratedt.pm,v 1.104 2011/11/14 00:20:46 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
package Apache::lonratedt;
use strict;
use Apache::Constants qw(:common);
use Apache::lonnet;
use Apache::lonsequence();
use Apache::loncommon();
use Apache::lonlocal;
use LONCAPA::map();
use File::Copy;
use LONCAPA;
use HTML::Entities();
# --------------------------------------------------------- Build up RAT screen
sub ratedt {
my ($r,$url)=@_;
my %layout = ('border' => "0",
'rows' => "1,250,*");
my $js ='
';
my $start_page =
&Apache::loncommon::start_page('Edit Sequence',$js,
{'frameset' => 1,
'add_entries' => \%layout});
my $end_page =
&Apache::loncommon::end_page({'frameset' => 1});
$r->print(<
$end_page
ENDDOCUMENT
}
# ---------------------------------------------------------------- Make buttons
sub buttons {
my $adv=shift;
my $output='
';
}
# ----------------------------------------------------------------- Edit script
sub editscript {
my $mode=shift;
my $resurl=
&Apache::loncommon::escape_single(&Apache::loncommon::lastresurl());
return(<'.&mt('Saved.').' ';
} else {
$targetmsg=''.&mt('An error occurred while saving.').' ';
}
}
if ($env{'form.revert'}) {
$targetmsg=''.&mt('Reverted.').' ';
unlink($tmpfn);
my ($errtext,$fatal)=
&LONCAPA::map::mapread(&Apache::lonnet::filelocation('',$url),'');
}
if (-e $tmpfn) {
$targetmsg=
''.&mt('You are working with an unsaved version of your map.').' ';
my ($errtext,$fatal)=&LONCAPA::map::mapread($tmpfn,'');
}
# ---------------------------------------------------------- Process form input
my @importselect=&Apache::loncommon::get_env_multiple('form.importsel');
my @targetselect=&Apache::loncommon::get_env_multiple('form.target');
# ============================================================ Process commands
my $targetdetail=$env{'form.targetdetail'};
my $importdetail=$env{'form.curimpdetail'};
# ---------------------------------------------------- Importing from groupsort
if (($env{'form.importdetail'}) && (!$env{'form.impfortarget'})) {
$importdetail='';
my @curimport=split(/\&/,$env{'form.curimpdetail'});
my $lastsel;
if (defined($importselect[-1])) {
$lastsel=$importselect[-1];
} else {
$lastsel=$#curimport;
}
for (my $i=0;$i<=$lastsel;$i++) {
my ($name,$url)=split(/\=/,$curimport[$i]);
if ($url) {
$importdetail.='&'.$name.'='.$url;
}
}
$importdetail.='&'.$env{'form.importdetail'};
for (my $i=$lastsel+1;$i<=$#curimport;$i++) {
my ($name,$url)=split(/\=/,$curimport[$i]);
if ($url) {
$importdetail.='&'.$name.'='.$url;
}
}
$importdetail=~s/\&+/\&/g;
$importdetail=~s/^\&//;
# ------------------------------------------------------------------- Clear all
} elsif ($env{'form.clear'}) {
$importdetail='';
# ------------------------------------------------------------ Discard selected
} elsif ($env{'form.discard'}) {
$importdetail='';
my @curimport=split(/\&/,$env{'form.curimpdetail'});
foreach (@importselect) {
$curimport[$_]='';
}
for (my $i=0;$i<=$#curimport;$i++) {
my ($name,$url)=split(/\=/,$curimport[$i]);
if ($url) {
$importdetail.='&'.$name.'='.$url;
}
}
# --------------------------------------------------------- Loading another map
} elsif ($env{'form.loadmap'}) {
$importdetail='';
my @curimport=split(/\&/,$env{'form.curimpdetail'});
my $lastsel;
if (defined($importselect[-1])) {
$lastsel=$importselect[-1];
} else {
$lastsel=$#curimport;
}
for (my $i=0;$i<=$lastsel;$i++) {
my ($name,$url)=split(/\=/,$curimport[$i]);
if ($url) {
$importdetail.='&'.$name.'='.$url;
}
}
foreach (
&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$env{'form.importmap'}))) {
my ($name,$url)=split(/\:/,$_);
if ($url) {
$importdetail.='&'.&escape($name).'='.
&escape($url);
}
}
for (my $i=$lastsel+1;$i<=$#curimport;$i++) {
my ($name,$url)=split(/\=/,$curimport[$i]);
if ($url) {
$importdetail.='&'.$name.'='.$url;
}
}
$importdetail=~s/\&+/\&/g;
$importdetail=~s/^\&//;
# ------------------------------------------------ Groupimport/search to target
} elsif ($env{'form.importdetail'}) {
my $lastsel;
if (defined($targetselect[-1])) {
$lastsel=$targetselect[-1];
} else {
$lastsel=$#LONCAPA::map::order+1;
}
&LONCAPA::map::pastetarget($lastsel,split(/\&/,$env{'form.importdetail'}));
&LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
# ------------------------------------------------------------------------- Cut
} elsif (($env{'form.cut'}) || ($env{'form.copy'})) {
$importdetail='';
my @curimport=split(/\&/,$env{'form.curimpdetail'});
my $lastsel;
if (defined($importselect[-1])) {
$lastsel=$importselect[-1];
} else {
$lastsel=$#curimport;
}
for (my $i=0;$i<=$lastsel;$i++) {
my ($name,$url)=split(/\=/,$curimport[$i]);
if ($url) {
$importdetail.='&'.$name.'='.$url;
}
}
foreach (@targetselect) {
my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$LONCAPA::map::order[$_-1]]);
if ($url) {
$importdetail.='&'.&escape($name).'='.
&escape($url);
}
}
for (my $i=$lastsel+1;$i<=$#curimport;$i++) {
my ($name,$url)=split(/\=/,$curimport[$i]);
if ($url) {
$importdetail.='&'.$name.'='.$url;
}
}
$importdetail=~s/\&+/\&/g;
$importdetail=~s/^\&//;
if ($env{'form.cut'}) {
my @neworder=();
for (my $i=0;$i<=$#LONCAPA::map::order;$i++) {
my $include=1;
foreach (@targetselect) {
if ($_-1==$i) { $include=0; }
}
if ($include) {
$neworder[$#neworder+1]=$LONCAPA::map::order[$i];
} else {
&LONCAPA::map::makezombie($LONCAPA::map::order[$i]);
}
}
@LONCAPA::map::order=@neworder;
&LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
}
# ----------------------------------------------------------------------- Paste
} elsif ($env{'form.paste'}) {
my $lastsel;
if (defined($targetselect[-1])) {
$lastsel=$targetselect[-1];
} else {
$lastsel=$#LONCAPA::map::order+1;
}
my @newsequence;
my @curimport=split(/\&/,$env{'form.curimpdetail'});
foreach (@importselect) {
$newsequence[$#newsequence+1]=$curimport[$_];
}
&LONCAPA::map::pastetarget($lastsel,@newsequence);
&LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
# -------------------------------------------------------------------- Move up
} elsif ($env{'form.moveup'}) {
foreach (sort @targetselect) {
if ($_-1>0) {
my $movethis=$LONCAPA::map::order[$_-1];
$LONCAPA::map::order[$_-1]=$LONCAPA::map::order[$_-2];
$LONCAPA::map::order[$_-2]=$movethis;
}
}
&LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
# ------------------------------------------------------------------ Move down
} elsif ($env{'form.movedown'}) {
foreach (reverse sort @targetselect) {
if ($_-1<$#LONCAPA::map::order) {
my $movethis=$LONCAPA::map::order[$_-1];
$LONCAPA::map::order[$_-1]=$LONCAPA::map::order[$_];
$LONCAPA::map::order[$_]=$movethis;
}
}
&LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
# --------------------------------------------------------------------- Rename
} elsif ($env{'form.renameres'}) {
my $residx=$LONCAPA::map::order[$env{'form.renameidx'}-1];
my ($name,@resrest)=split(/\:/,$LONCAPA::map::resources[$residx]);
$name=$env{'form.renametitle'};
$name=~s/\:/\&colon\;/g;
$LONCAPA::map::resources[$residx]=$name.':'.join(':',@resrest);
&LONCAPA::map::storemap(&Apache::lonnet::filelocation('',$url));
}
# ------------------------------------------------------------ Assemble windows
my $idx=-1;
$importdetail='&'.$importdetail;
$importdetail=~s/^\&+/\&/;
my $importwindow=
''.
join("\n",map {
$idx++;
if ($_) {
my ($name,$url)=split(/\=/,$_);
unless ($name) { $name=(split(/\//,$url))[-1]; }
unless ($name) { $name='EMPTY'; }
'';
}
} split(/\&/,$importdetail));
$idx=0;
$targetdetail='';
my $targetwindow=
''.
join("\n",map {
my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$_]);
unless ($name) { $name=(split(/\//,$url))[-1]; }
unless ($name) { $name='EMPTY'; }
$name = &LONCAPA::map::qtescape($name);
$url = &LONCAPA::map::qtescape($url);
$targetdetail.='&'.&escape($name).'='.
&escape($url);
$idx++;
$name = &HTML::Entities::encode($name,'\'"<>&');
'';
} @LONCAPA::map::order);
# ----------------------------------------------------- Start simple RAT screen
my $editscript=&editscript('simple');
my %lt=&Apache::lonlocal::texthash(
'sa' => 'Save',
'nt' => 'New Title',
'se' => 'Search',
'im' => 'Import',
'wl' => 'Import from Wishlist',
'vi' => 'View',
'lm' => 'Load Map',
'ds' => 'Discard Selected',
'ca' => 'Clear All',
'ta' => 'Temporary Assembly Workspace',
'rv' => 'Revert to Last Saved',
'sa' => 'Save',
'mu' => 'Move Up',
'md' => 'Move Down',
're' => 'Rename',
'as' => 'after selected',
'cs' => 'Cut selected',
'ps' => 'Copy selected',
'pas' => 'Paste after selected',
'reco' => 'Recover Deleted'
);
my $js=<
$editscript
function openview(entry) {
var url=unescape((entry.split('='))[1]);
var parts=new Array;
if (url) { open(url,'cat'); }
}
function viewtarget() {
openview((document.forms.simpleedit.targetdetail.value.split('&'))
[document.forms.simpleedit.target.selectedIndex]);
}
function viewimport() {
openview((document.forms.simpleedit.curimpdetail.value.split('&'))
[document.forms.simpleedit.importsel.selectedIndex]);
}
function renametarget() {
var selidx=document.forms.simpleedit.target.selectedIndex;
var entry=(document.forms.simpleedit.targetdetail.value.split('&'))
[selidx];
var oldname=unescape((entry.split('='))[0]);
newtitle=prompt('$lt{'nt'}',oldname);
if (newtitle) {
document.forms.simpleedit.renameres.value=1;
document.forms.simpleedit.renameidx.value=selidx;
document.forms.simpleedit.renametitle.value=newtitle;
document.forms.simpleedit.submit();
}
}
ENDJS
&Apache::lonhtmlcommon::clear_breadcrumbs();
&Apache::lonhtmlcommon::add_breadcrumb({
text => 'Construction Space',
href => &Apache::loncommon::authorspace($url),
faq => 6,
bug => 'RAT',
help => 'Sequence_Simple_Editor_Creation',});
&Apache::lonhtmlcommon::add_breadcrumb({
text => 'RAT',
title => 'Resource Assembly Tool',
href => '',});
&Apache::lonhtmlcommon::add_breadcrumb({
text => 'Editor',
title => 'Simple Editor',
href => '',});
# Breadcrumbs are included by &start_page
my $start_page = &Apache::loncommon::start_page('Construction Space',$js)
.&Apache::loncommon::head_subbox(
&Apache::loncommon::CSTR_pageheader()
.&buttons(2));
my $end_page = &Apache::loncommon::end_page();
$r->print(<$errtext
$end_page
ENDSMPHEAD
}
# ----------------------------------------------------------------- No such dir
sub nodir {
my ($r,$dir)=@_;
my $londocroot = $r->dir_config('lonDocRoot');
my ($path) = ($dir =~ m{^\Q$londocroot\E?(/priv/[^/]+/[^/]+/)});
$dir=~s{^\Q$londocroot/priv/\E[^/]+/[^/]+}{};
my $brcrum = [{'href' => &Apache::loncommon::authorspace($path),
'text' => 'Construction Space'}];
# {'href' => '',
# 'text' => 'No such directory'}];
$r->print(&Apache::loncommon::start_page('Construction Space',
undef,
{'bread_crumbs' => $brcrum,})
.&Apache::loncommon::head_subbox(
&Apache::loncommon::CSTR_pageheader())
.'
'
.&mt('No such directory: [_1]',''.$dir.''
.'
'
.&Apache::loncommon::end_page())
);
}
# ---------------------------------------------------------------- View Handler
sub viewmap {
my ($r,$url,$adv,$errtext)=@_;
&Apache::lonhtmlcommon::clear_breadcrumbs();
&Apache::lonhtmlcommon::add_breadcrumb({
text => 'Construction Space',
href => &Apache::loncommon::authorspace($url),
faq => 6,
bug => 'RAT',
help => 'Sequence_Simple_Editor_Creation',});
&Apache::lonhtmlcommon::add_breadcrumb({
text => 'RAT',
title => 'Resource Assembly Tool',
href => '',});
# Breadcrumbs are included by &start_page
$r->print(&Apache::loncommon::start_page('Edit Content of a Map')
.&Apache::loncommon::head_subbox(
&Apache::loncommon::CSTR_pageheader()
.&buttons($adv))
);
if ($errtext) {
$r->print('
'
.&Apache::loncommon::end_data_table_row()
);
}
}
$r->print(&Apache::loncommon::end_data_table());
$r->print(&Apache::loncommon::end_page());
}
# ================================================================ Main Handler
sub handler {
my $r=shift;
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
return OK if $r->header_only;
my $target = $env{'form.grade_target'};
if ($target eq 'meta') {
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
return OK;
}
my $url=$r->uri;
my $fn=&Apache::lonnet::filelocation('',$url);
my ($dir)=($fn=~/^(.+)\/[^\/]+$/);
unless (-e $dir) {
&nodir($r,$dir);
return OK;
}
# ------------------------------------------- Determine which tools can be used
my $adv=0;
unless ($env{'form.forcesmp'}) {
if ($env{'form.forceadv'}) {
$adv=1;
} elsif (my $fh=Apache::File->new($fn)) {
my $allmap=join('',<$fh>);
$adv=($allmap=~/\