Annotation of loncom/interface/lonextresedit.pm, revision 1.1

1.1     ! raeburn     1: # The LearningOnline Network
        !             2: # Documents
        !             3: #
        !             4: # $Id: lonextresedit.pm,v 1.1 2012/11/22 12:03:19 raeburn Exp $
        !             5: #
        !             6: # Copyright Michigan State University Board of Trustees
        !             7: #
        !             8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
        !             9: #
        !            10: # LON-CAPA is free software; you can redistribute it and/or modify
        !            11: # it under the terms of the GNU General Public License as published by
        !            12: # the Free Software Foundation; either version 2 of the License, or
        !            13: # (at your option) any later version.
        !            14: #
        !            15: # LON-CAPA is distributed in the hope that it will be useful,
        !            16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            18: # GNU General Public License for more details.
        !            19: #
        !            20: # You should have received a copy of the GNU General Public License
        !            21: # along with LON-CAPA; if not, write to the Free Software
        !            22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            23: #
        !            24: # /home/httpd/html/adm/gpl.txt
        !            25: #
        !            26: # http://www.lon-capa.org/
        !            27: #
        !            28: 
        !            29: package Apache::lonextresedit;
        !            30: 
        !            31: use strict;
        !            32: use Apache::Constants qw(:common :http);
        !            33: use HTML::Entities;
        !            34: use Apache::lonlocal;
        !            35: use Apache::lonnet;
        !            36: use Apache::loncommon;
        !            37: use Apache::lonhtmlcommon;
        !            38: use Apache::lonuserstate;
        !            39: use LONCAPA::map();
        !            40: use LONCAPA qw(:DEFAULT :match);
        !            41: 
        !            42: sub handler {
        !            43:     my $r=shift;
        !            44:     &Apache::loncommon::content_type($r,'text/html');
        !            45:     $r->send_http_header;
        !            46: 
        !            47:     return OK if $r->header_only;
        !            48: 
        !            49:     # Check for access
        !            50:     if (! &Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
        !            51:         $env{'user.error.msg'}=
        !            52:             $r->uri.":mdc:0:0:Cannot modify course content.";
        !            53:             return HTTP_NOT_ACCEPTABLE;
        !            54:     }
        !            55: 
        !            56:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
        !            57:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
        !            58:     my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
        !            59:     my ($supplementalflag,$updated,$output,$errormsg,$residx,$url,$title,$symb);
        !            60:     if ((($env{'form.folderpath'} =~ /^supplemental/) && ($env{'form.suppurl'})) ||
        !            61:         ($env{'form.symb'} =~ /^uploaded/)) {
        !            62:         $supplementalflag = 1;        
        !            63:         ($updated,$output,$errormsg,$residx,$url,$title,$symb) = 
        !            64:             &process_changes($supplementalflag,$cdom,$cnum,$chome);
        !            65:         if ($supplementalflag) {
        !            66:             if ($url ne $env{'form.suppurl'}) {
        !            67:                  $env{'form.suppurl'} = $url;
        !            68:             }
        !            69:             if ($title ne $env{'form.title'}) {
        !            70:                 $env{'form.title'} = $title;
        !            71:             }
        !            72:         } else {
        !            73:             if ($symb ne $env{'form.symb'}) {
        !            74:                 $env{'form.symb'} = $symb;
        !            75:             }
        !            76:         }
        !            77:     } else {
        !            78:         $errormsg = &mt('Information about external resource to edit is missing.');
        !            79:     }
        !            80:     if ($updated) {
        !            81:         $output = &Apache::lonhtmlcommon::confirm_success(&mt('External Resource updated'));
        !            82:     }
        !            83:     if ($errormsg) {
        !            84:         $errormsg = '<p class="LC_error">'.$errormsg.'</p>';
        !            85:     }
        !            86:     my $js = &Apache::lonhtmlcommon::scripttag(&extedit_javascript());
        !            87:     my $pathitem = '<input type="hidden" name="folderpath" value="'.
        !            88:                    &HTML::Entities::encode($env{'form.folderpath'},'<>&"').'" />';
        !            89:     $r->print(&Apache::loncommon::start_page('External Resource Editor',$js).
        !            90:               '<div class="LC_left_float">'.
        !            91:               $output.
        !            92:               $errormsg.
        !            93:               &extedit_form($supplementalflag,$residx,$url,$title,$pathitem,undef,
        !            94:                            'direct',$env{'form.symb'}).
        !            95:               '</div>'.&Apache::loncommon::end_page());
        !            96:     return OK;
        !            97: }
        !            98: 
        !            99: sub process_changes {
        !           100:     my ($supplementalflag,$cdom,$cnum,$chome) = @_;
        !           101:     my ($folder,$container,$output,$errormsg,$updated,$symb,$oldidx,$oldurl,
        !           102:         $oldtitle,$residx,$newurl,$newtitle);
        !           103:     if ($env{'form.symb'}) {
        !           104:         $symb = $env{'form.symb'};
        !           105:         (my $map,$oldidx,my $url)=&Apache::lonnet::decode_symb($symb);
        !           106:         if ($map =~ m{^uploaded/$cdom/$cnum/(default(_\d+|))\.(sequence|page)$}) {
        !           107:             $folder = $1;
        !           108:             $container = $3;
        !           109:         }
        !           110:         if ($url =~ m{^ext/(.+)$}) {
        !           111:             $oldurl = $1;
        !           112:             if ($oldurl !~ m{^https://}) {
        !           113:                 $oldurl = 'http://'.$oldurl;
        !           114:             }
        !           115:         }
        !           116:         $oldtitle = &Apache::lonnet::gettitle($env{'form.symb'});
        !           117:     } elsif ($env{'form.folderpath'}) {
        !           118:         $folder = &unescape( (split('&',$env{'form.folderpath'}))[-2] );
        !           119:         $oldurl = &unescape($env{'form.suppurl'});
        !           120:         $oldtitle = &unescape($env{'form.title'});
        !           121:         $container = 'sequence';
        !           122:         $supplementalflag = 1;
        !           123:     }
        !           124:     if ($folder && $container) {
        !           125:         if ($env{'form.importdetail'}) {
        !           126:             my ($errtext,$fatal,$mismatchedid);
        !           127:             ($newtitle,$newurl, $residx) =
        !           128:                 map {&unescape($_)} split(/\=/,$env{'form.importdetail'});
        !           129:             if (!$supplementalflag && $oldidx) {
        !           130:                if ($oldidx != $residx) {
        !           131:                    $mismatchedid = 1;
        !           132:                    $residx = $oldidx;
        !           133:                }
        !           134:             }
        !           135:             my @imports;
        !           136:             if ($mismatchedid) {
        !           137:                 $errormsg = 'Wrong item identifier';
        !           138:             } elsif (($newtitle eq $oldtitle) && ($newurl eq $oldurl)) {
        !           139:                 $output = &mt('No change');
        !           140:             } else {
        !           141:                 my $map = "/uploaded/$cdom/$cnum/$folder.$container";
        !           142:                 my ($errtext,$fatal) = &LONCAPA::map::mapread($map);
        !           143:                 if ($fatal) {
        !           144:                     $errormsg = &mt('Update failed: [_1].',$errtext);
        !           145:                 } else {
        !           146:                     my $saveurl = &LONCAPA::map::qtunescape($newurl);
        !           147:                     my $savetitle = &LONCAPA::map::qtunescape($newtitle);
        !           148:                     $LONCAPA::map::resources[$residx] =
        !           149:                         join(':', ($savetitle,$saveurl,'true','normal','res'));
        !           150:                     my ($outtext,$errtext) = &LONCAPA::map::storemap($map,1);
        !           151:                     if ($errtext) {
        !           152:                         $errormsg = &mt('Update failed: [_1].',$errtext);
        !           153:                     } else {
        !           154:                         $updated = 1;
        !           155:                         if (!$supplementalflag) {
        !           156:                             if ($newurl ne $oldurl) {
        !           157:                                 $symb = &Apache::lonnet::encode_symb($map,$residx,"ext/$newurl");
        !           158:                             } else {
        !           159:                                 $symb = $env{'form.symb'};
        !           160:                                 if ($symb) {
        !           161:                                     &Apache::lonnet::devalidate_title_cache($symb);
        !           162:                                 }
        !           163:                             }
        !           164:                         }
        !           165:                         my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum");
        !           166:                         if ($ferr) {
        !           167:                             $errormsg = &mt('Reload failed: [_1].',$ferr);
        !           168:                         } else {
        !           169:                             &Apache::loncommon::update_content_constraints($cdom,$cnum,$chome,
        !           170:                                                                            $cdom.'_'.$cnum);
        !           171:                         }
        !           172:                     }
        !           173:                 }
        !           174:             }
        !           175:         } else {
        !           176:             $output = &mt('No change');
        !           177:         }
        !           178:     } else {
        !           179:         $errormsg = &mt('Information about current external resource is incomplete.');
        !           180:     }
        !           181:     if ($updated) {
        !           182:         return ($updated,$output,$errormsg,$residx,$newurl,$newtitle,$symb);
        !           183:     } else {
        !           184:         return ($updated,$output,$errormsg,$residx,$oldurl,$oldtitle,$symb);
        !           185:     }
        !           186: }
        !           187: 
        !           188: sub extedit_form {
        !           189:     my ($supplementalflag,$residx,$orig_url,$orig_title,$pathitem,$helpitem,$caller,$symb) = @_;
        !           190:     my %lt = &Apache::lonlocal::texthash(
        !           191:         ex => 'External Resource',
        !           192:         ed => 'Edit',
        !           193:         ee => 'External Resource Editor',
        !           194:         pr => 'Preview',
        !           195:         sv => 'Save',
        !           196:         ul => 'URL',
        !           197:         ti => 'Title',
        !           198:         al => 'Add Link',
        !           199:     );
        !           200:     my $formname = 'newext';
        !           201:     my $tabid = 'aa';
        !           202:     my $toggle = 'ext';
        !           203:     my $fieldsetid = 'uploadextform';
        !           204:     my $urlid = 'exturl';
        !           205:     my $size = 60;
        !           206:     if ($supplementalflag) {
        !           207:         $formname = 'newsuppext';
        !           208:         $tabid = 'ee';
        !           209:         $toggle = 'suppext';
        !           210:         $fieldsetid = 'uploadsuppextform';
        !           211:         $urlid = 'suppexturl';
        !           212:     }
        !           213:     my ($link,$legend,$active,$srcclass,$extsrc,$preview,$title,$save,
        !           214:         $fieldsetstyle,$action,$hiddenelem);
        !           215:     $fieldsetstyle = 'display: none;';
        !           216:     $action = '/adm/coursedocs';
        !           217:     if ($residx) {
        !           218:         if ($caller eq 'direct') {
        !           219:             $fieldsetstyle = 'display: block;';
        !           220:             $action = '/adm/extresedit';
        !           221:             $legend = "<legend>$lt{'ee'}</legend>";
        !           222:             if ($symb) {
        !           223:                 $hiddenelem = '<input type="hidden" name="symb" value="'.$symb.'" />';
        !           224:             } elsif ($supplementalflag) {
        !           225:                 $hiddenelem = '<input type="hidden" name="suppurl" value="'.
        !           226:                               &HTML::Entities::encode(&escape($orig_url),'<>&"').'" />'."\n".
        !           227:                               '<input type="hidden" name="title" value="'.
        !           228:                               &HTML::Entities::encode(&escape($orig_title),'<>&"').'" />';
        !           229:             }
        !           230:         } else {        
        !           231:             $link = '<a class="LC_docs_ext_edit" href="javascript:editext('."'$residx'".');">'.$lt{'ed'}.'</a>';
        !           232:             $size = 40;
        !           233:             $active = '<input type="hidden" name="active" value="'.$tabid.'" />'; 
        !           234:         }
        !           235:         $formname = "editext_$residx";
        !           236:         $fieldsetid = "uploadext$residx";
        !           237:         $urlid = "exturl_$residx";
        !           238:         $srcclass = ' class="LC_nobreak"';
        !           239:         $extsrc = '<span class="LC_docs_ext_edit">'.$lt{'ul'}.'&nbsp;</span>';
        !           240:         $preview = '&nbsp;<a class="LC_docs_ext_edit" href="javascript:extUrlPreview('."'$urlid'".');">'.$lt{'pr'}.'</a>';
        !           241:         $title = '<span class="LC_docs_ext_edit">'.$lt{'ti'}.'&nbsp;</span>';
        !           242:         $save = $lt{'sv'};
        !           243:     } else {
        !           244:         $link = '<a class="LC_menubuttons_link" href="javascript:toggleUpload('."'$toggle'".');">'.$lt{'ex'}.'</a>'.$helpitem;
        !           245:         $legend = "<legend>$lt{'ex'}</legend>";
        !           246:         $extsrc = $lt{'ul'}.':<br />';
        !           247:         $title = $lt{'ti'}.':<br />';
        !           248:         $residx = 0;
        !           249:         $orig_url = 'http://';
        !           250:         $orig_title = $lt{'ex'};
        !           251:         $preview = '<input type="button" name="view" value="'.$lt{'pr'}.'" onclick="javascript:extUrlPreview('."'$urlid'".');" />';
        !           252:         $save = $lt{'al'};
        !           253:         $pathitem .= '<br />';
        !           254:     }
        !           255:     return <<ENDFORM
        !           256: $link
        !           257: <form action="$action" method="post" name="$formname">
        !           258: <fieldset id="$fieldsetid" style="$fieldsetstyle" />
        !           259: $legend
        !           260: $active
        !           261: <span$srcclass>
        !           262: $extsrc
        !           263: <input type="text" size="$size" name="exturl" id="$urlid" value="$orig_url" />
        !           264: $preview
        !           265: </span> 
        !           266: <br />
        !           267: <span$srcclass>
        !           268: $title
        !           269: <input type="text" size="$size" name="exttitle" value="$orig_title" />
        !           270: <input type="hidden" name="importdetail" value="" />
        !           271: $pathitem
        !           272: $hiddenelem
        !           273: <input type="button" value="$save" onclick="javascript:setExternal(this.form,'$residx');" />
        !           274: </span>
        !           275: </fieldset>
        !           276: </form>
        !           277: ENDFORM
        !           278: 
        !           279: }
        !           280: 
        !           281: sub display_editor {
        !           282:     my ($url,$folderpath,$symb,$idx) = @_;
        !           283:     my ($residx,$supplementalflag,$title,$pathitem,$output);
        !           284:     if ($folderpath =~ /^supplemental/) {
        !           285:         $supplementalflag = 1;
        !           286:         $residx = $idx;
        !           287:         $title = &unescape($env{'form.title'});
        !           288:         $pathitem = '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($folderpath,'<>&"').'" />';
        !           289:     } elsif ($symb =~ /^uploaded/) {
        !           290:         (my $map,$residx,my $res) =
        !           291:             &Apache::lonnet::decode_symb($symb);
        !           292:         $title = &Apache::lonnet::gettitle($symb);
        !           293:         my $path = &Apache::lonnet::getdocspath($symb);
        !           294:         if ($map =~ /\.page$/) {
        !           295:             $pathitem = '<input type="hidden" name="pagepath" value="'.&HTML::Entities::encode($path,'<>&"').'" />';
        !           296:         } else {
        !           297:             $pathitem = '<input type="hidden" name="folderpath" value="'.&HTML::Entities::encode($path,'<>&"').'" />';
        !           298:         }
        !           299:     }
        !           300:     my $js = &Apache::lonhtmlcommon::scripttag(&extedit_javascript());
        !           301:     my $args = { 'force_register' => $env{'form.register'} };
        !           302:     return &Apache::loncommon::start_page('External Resource Editor',$js,$args).
        !           303:            '<div class="LC_left_float">'.
        !           304:            &extedit_form($supplementalflag,$residx,$url,$title,$pathitem,undef,'direct',$symb).
        !           305:            '</div>'.
        !           306:            &Apache::loncommon::end_page();
        !           307: }
        !           308: 
        !           309: sub extedit_javascript {
        !           310:     my %lt = &Apache::lonlocal::texthash(
        !           311:         invurl  => 'Invalid URL',
        !           312:         titbl   => 'Title is blank',
        !           313:     );
        !           314: 
        !           315:     my $urlregexp = <<'ENDREGEXP';
        !           316: /^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i
        !           317: ENDREGEXP
        !           318: 
        !           319:     return <<ENDJS;
        !           320: 
        !           321: var regexp = $urlregexp;
        !           322: 
        !           323: function setExternal(extform,residx) {
        !           324:     var title=extform.exttitle.value;
        !           325:     if (!String.trim) {
        !           326:         String.prototype.trim = function() {return this.replace(\/^\\s+|\\s+$\/g, "");};    }
        !           327:     var url=extform.exturl.value;
        !           328:     if (title == null || title.trim()=="") {
        !           329:         alert("$lt{'titbl'}");
        !           330:         extform.exttitle.focus();
        !           331:         return;
        !           332:     }
        !           333:     if (regexp.test(url)) {
        !           334:         url = escape(url);
        !           335:         if (residx > 0) {
        !           336:             eval("extform.importdetail.value=title+'='+url+'='+residx;extform.submit();");
        !           337:         } else {
        !           338:             eval("extform.importdetail.value=title+'='+url;extform.submit();");
        !           339:         }
        !           340:     } else {
        !           341:         alert("$lt{'invurl'}");
        !           342:         extform.exturl.focus();
        !           343:         return;
        !           344:     }
        !           345: }
        !           346: 
        !           347: function editext(residx) {
        !           348:     if (document.getElementById('uploadext'+residx)) {
        !           349:         var curr = document.getElementById('uploadext'+residx).style.display;
        !           350:         if (curr == 'none') {
        !           351:             disp = 'block';
        !           352:         } else {
        !           353:             disp = 'none';
        !           354:         }
        !           355:         document.getElementById('uploadext'+residx).style.display=disp;
        !           356:     }
        !           357:     resize_scrollbox('contentscroll','1','1');
        !           358:     return;
        !           359: }
        !           360: 
        !           361: function extUrlPreview(caller) {
        !           362:     if (document.getElementById(caller)) {
        !           363:         var url = document.getElementById(caller).value;
        !           364:         if (regexp.test(url)) {
        !           365:             openMyModal(url,500,400,'yes');
        !           366:         } else {
        !           367:             alert("$lt{'invurl'}");
        !           368:         }
        !           369:     }
        !           370: }
        !           371: 
        !           372: ENDJS
        !           373: 
        !           374: }
        !           375: 
        !           376: 1;

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