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'}.' </span>';
! 240: $preview = ' <a class="LC_docs_ext_edit" href="javascript:extUrlPreview('."'$urlid'".');">'.$lt{'pr'}.'</a>';
! 241: $title = '<span class="LC_docs_ext_edit">'.$lt{'ti'}.' </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>