2 rcs_id('$Id: editpage.php,v 1.77 2004-11-15 15:52:35 rurban Exp $');
4 require_once('lib/Template.php');
6 // USE_HTMLAREA - Support for some WYSIWYG HTML Editor
7 // Not yet enabled, since we cannot convert HTML to Wiki Markup yet.
8 // (See HtmlParser.php for the ongoing efforts)
9 // We might use a HTML PageType, which is contra wiki, but some people might prefer HTML markup.
10 // TODO: Change from constant to user preference variable (checkbox setting),
11 // when HtmlParser is finished.
12 if (!defined('USE_HTMLAREA')) define('USE_HTMLAREA',false);
13 if (USE_HTMLAREA) require_once('lib/htmlarea.php');
17 function PageEditor (&$request) {
18 $this->request = &$request;
20 $this->user = $request->getUser();
21 $this->page = $request->getPage();
23 $this->current = $this->page->getCurrentRevision(false);
25 // HACKish short circuit to browse on action=create
26 if ($request->getArg('action') == 'create') {
27 if (! $this->current->hasDefaultContents())
28 $request->redirect(WikiURL($this->page->getName())); // noreturn
32 $this->meta = array('author' => $this->user->getId(),
33 'author_id' => $this->user->getAuthenticatedId(),
36 $this->tokens = array();
38 $version = $request->getArg('version');
39 if ($version !== false) {
40 $this->selected = $this->page->getRevision($version);
41 $this->version = $version;
44 $this->version = $this->current->getVersion();
45 $this->selected = $this->page->getRevision($this->version);
48 if ($this->_restoreState()) {
49 $this->_initialEdit = false;
52 $this->_initializeState();
53 $this->_initialEdit = true;
55 // The edit request has specified some initial content from a template
56 if ( ($template = $request->getArg('template')) and
57 $request->_dbi->isWikiPage($template)) {
58 $page = $request->_dbi->getPage($template);
59 $current = $page->getCurrentRevision();
60 $this->_content = $current->getPackedContent();
61 } elseif ($initial_content = $request->getArg('initial_content')) {
62 $this->_content = $initial_content;
63 $this->_redirect_to = $request->getArg('save_and_redirect_to');
67 header("Content-Type: text/html; charset=" . $GLOBALS['charset']);
70 function editPage () {
73 $tokens = &$this->tokens;
75 if (! $this->canEdit()) {
76 if ($this->isInitialEdit())
77 return $this->viewSource();
78 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
80 elseif ($this->request->getArg('save_and_redirect_to') != "") {
81 if ($this->savePage()) {
83 $this->request->redirect(WikiURL($this->request->getArg('save_and_redirect_to')));
84 return true; // Page saved.
88 elseif ($this->editaction == 'save') {
89 if ($this->savePage()) {
90 return true; // Page saved.
95 if ($saveFailed || $this->isConcurrentUpdate())
97 // Get the text of the original page, and the two conflicting edits
98 // The diff3 class takes arrays as input. So retrieve content as
99 // an array, or convert it as necesary.
100 $orig = $this->page->getRevision($this->_currentVersion);
101 // FIXME: what if _currentVersion has be deleted?
102 $orig_content = $orig->getContent();
103 $this_content = explode("\n", $this->_content);
104 $other_content = $this->current->getContent();
105 include_once("lib/diff3.php");
106 $diff = new diff3($orig_content, $this_content, $other_content);
107 $output = $diff->merged_output(_("Your version"), _("Other version"));
108 // Set the content of the textarea to the merged diff
109 // output, and update the version
110 $this->_content = implode ("\n", $output);
111 $this->_currentVersion = $this->current->getVersion();
112 $this->version = $this->_currentVersion;
113 $unresolved = $diff->ConflictingBlocks;
114 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage($unresolved);
117 if ($this->editaction == 'preview')
118 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
120 // FIXME: NOT_CURRENT_MESSAGE?
121 $tokens = array_merge($tokens, $this->getFormElements());
123 //FIXME: enable Undo button for all other buttons also, not only the search/replace button
124 if (defined('JS_SEARCHREPLACE') and JS_SEARCHREPLACE) {
125 $tokens['JS_SEARCHREPLACE'] = 1;
126 $undo_btn = $WikiTheme->getImageURL("ed_undo.gif");
127 $undo_d_btn = $WikiTheme->getImageURL("ed_undo_d.gif");
128 // JS_SEARCHREPLACE from walterzorn.de
129 $WikiTheme->addMoreHeaders(Javascript("
130 var f, sr_undo, replacewin, undo_buffer=new Array(), undo_buffer_index=0;
132 function define_f() {
133 f=document.getElementById('editpage');
134 f.editarea=document.getElementById('edit[content]');
135 sr_undo=document.getElementById('sr_undo');
139 function undo_enable(bool) {
141 sr_undo.src='".$undo_btn."';
145 sr_undo.disabled = false;
147 sr_undo.src='".$undo_d_btn."';
151 sr_undo.disabled = true;
152 if(sr_undo.blur) sr_undo.blur();
157 replacewin = window.open('','','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,height=90,width=450');
158 replacewin.window.document.write('<html><head><title>"
159 ._("Search & Replace")
160 ."</title><style type=\"text/css\"><'+'!'+'-- body, input {font-family:Tahoma,Arial,Helvetica,sans-serif;font-size:10pt;font-weight:bold;} td {font-size:9pt} --'+'></style></head><body bgcolor=\"#dddddd\" onload=\"if(document.forms[0].ein.focus) document.forms[0].ein.focus()\"><form><center><table><tr><td align=\"right\">'+'"
162 .":</td><td align=\"left\"><input type=\"text\" name=\"ein\" size=\"45\" maxlength=\"500\"></td></tr><tr><td align=\"right\">'+' "
164 .":</td><td align=\"left\"><input type=\"text\" name=\"aus\" size=\"45\" maxlength=\"500\"></td></tr><tr><td colspan=\"2\" align=\"center\"><input type=\"button\" value=\" "
166 ." \" onclick=\"if(self.opener)self.opener.do_replace()\"> <input type=\"button\" value=\""
168 ."\" onclick=\"self.close()\"></td></tr></table></center></form></body></html>');
169 replacewin.window.document.close();
173 function do_replace() {
174 var txt=undo_buffer[undo_buffer_index]=f.editarea.value, ein=new RegExp(replacewin.document.forms[0].ein.value,'g'), aus=replacewin.document.forms[0].aus.value;
175 if(ein==''||ein==null) {
176 if (replacewin) replacewin.window.document.forms[0].ein.focus();
179 var z_repl=txt.match(ein)? txt.match(ein).length : 0;
180 txt=txt.replace(ein,aus);
181 ein=ein.toString().substring(1,ein.toString().length-2);
182 result(z_repl, 'Substring \"'+ein+'\" found '+z_repl+' times. Replace with \"'+aus+'\"?', txt, 'String \"'+ein+'\" not found.');
183 replacewin.window.focus();
184 replacewin.window.document.forms[0].ein.focus();
186 function result(zahl,frage,txt,alert_txt) {
188 if(window.confirm(frage)==true) {
189 f.editarea.value=txt;
193 } else alert(alert_txt);
196 if(undo_buffer_index==0) return;
197 else if(undo_buffer_index>0) {
198 f.editarea.value=undo_buffer[undo_buffer_index-1];
199 undo_buffer[undo_buffer_index]=null;
201 if(undo_buffer_index==0) {
202 alert('Operation undone.');
207 //save a snapshot in the undo buffer (unused)
209 undo_buffer[undo_buffer_index]=f.editarea.value;
214 $WikiTheme->addMoreAttr('body'," onload='define_f()'");
216 $WikiTheme->addMoreAttr('body',"document.getElementById('edit[content]').editarea.focus()");
218 if (defined('ENABLE_EDIT_TOOLBAR') and ENABLE_EDIT_TOOLBAR) {
219 $WikiTheme->addMoreHeaders(JavaScript('',array('src' => $WikiTheme->_findData("toolbar.js"))));
220 $tokens['EDIT_TOOLBAR'] = $this->toolbar();
222 $tokens['EDIT_TOOLBAR'] = '';
225 return $this->output('editpage', _("Edit: %s"));
228 function toolbar () {
232 "image"=>"ed_format_bold.gif",
235 "sample"=>_("Bold text"),
236 "tip"=>_("Bold text")),
237 array("image"=>"ed_format_italic.gif",
240 "sample"=>_("Italic text"),
241 "tip"=>_("Italic text")),
242 array("image"=>"ed_pagelink.gif",
245 "sample"=>_("optional label | PageName"),
246 "tip"=>_("Link to page")),
247 array("image"=>"ed_link.gif",
250 "sample"=>_("optional label | http://www.example.com"),
251 "tip"=>_("External link (remember http:// prefix)")),
252 array("image"=>"ed_headline.gif",
255 "sample"=>_("Headline text"),
256 "tip"=>_("Level 1 headline")),
257 array("image"=>"ed_image.gif",
260 "sample"=>_("Example.jpg"),
261 "tip"=>_("Embedded image")),
262 array("image"=>"ed_nowiki.gif",
263 "open"=>"\\n\\<verbatim\\>\\n",
264 "close"=>"\\n\\</verbatim\\>\\n",
265 "sample"=>_("Insert non-formatted text here"),
266 "tip"=>_("Ignore wiki formatting")),
267 array("image"=>"ed_sig.gif",
268 "open" => " --" . $GLOBALS['request']->_user->UserName(),
271 "tip"=>_("Your signature")),
272 array("image"=>"ed_hr.gif",
273 "open"=>"\\n----\\n",
276 "tip"=>_("Horizontal line"))
278 $toolbar = "document.writeln(\"<div class=\\\"edit-toolbar\\\" id=\\\"toolbar\\\">\");\n";
280 $btn = new SubmitImageButton(_("Save"), "edit[save]", 'toolbar', $WikiTheme->getImageURL("ed_save.gif"));
281 $btn->addTooltip(_("Save"));
282 $toolbar.='document.writeln("'.addslashes($btn->asXml()).'");'."\n";
283 $btn = new SubmitImageButton(_("Preview"), "edit[preview]", 'toolbar', $WikiTheme->getImageURL("ed_preview.gif"));
284 $btn->addTooltip(_("Preview"));
285 $toolbar.='document.writeln("'.addslashes($btn->asXml()).'");'."\n";
287 foreach ($toolarray as $tool) {
288 $image = $WikiTheme->getImageURL($tool["image"]);
289 $open = $tool["open"];
290 $close = $tool["close"];
291 $sample = addslashes( $tool["sample"] );
292 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
293 // Older browsers show a "speedtip" type message only for ALT.
294 // Ideally these should be different, realistically they
295 // probably don't need to be.
296 $tip = addslashes( $tool["tip"] );
297 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
299 $toolbar.="addInfobox('" . addslashes( _("Click a button to get an example text") ) . "');\n";
301 if (defined('JS_SEARCHREPLACE') and JS_SEARCHREPLACE) {
302 $undo_d_btn = $WikiTheme->getImageURL("ed_undo_d.gif");
303 //$redo_btn = $WikiTheme->getImageURL("ed_redo.gif");
304 $sr_btn = $WikiTheme->getImageURL("ed_replace.gif");
305 $sr_html = HTML(HTML::input(array('type' =>"image",
309 'title'=>_("Undo Search & Replace"),
310 'disabled'=>"disabled",
312 'onfocus' =>"if(this.blur && undo_buffer_index==0) this.blur()",
313 'onclick' =>"do_undo()")),
314 HTML::input(array('type' =>"image",
317 'title'=>_("Search & Replace"),
318 'onclick'=>"replace()")));
323 // Button to generate pagenames, display in extra window as pulldown and insert
324 // Button to generate plugins, display in extra window as pulldown and insert
325 // Button to generate categories, display in extra window as pulldown and insert
326 $toolbar_end = "document.writeln(\"</div>\");";
327 // don't use document.write for replace, otherwise self.opener is not defined.
329 return HTML(Javascript($toolbar),
331 Javascript($toolbar_end));
333 return HTML(Javascript($toolbar . $toolbar_end));
336 function output ($template, $title_fs) {
338 $selected = &$this->selected;
339 $current = &$this->current;
341 if ($selected && $selected->getVersion() != $current->getVersion()) {
343 $pagelink = WikiLink($selected);
347 $pagelink = WikiLink($this->page);
351 $title = new FormattedText ($title_fs, $pagelink);
352 if (USE_HTMLAREA and $template == 'editpage') {
353 $WikiTheme->addMoreHeaders(Edit_HtmlArea_Head());
354 //$tokens['PAGE_SOURCE'] = Edit_HtmlArea_ConvertBefore($this->_content);
356 $template = Template($template, $this->tokens);
357 GeneratePage($template, $title, $rev);
362 function viewSource () {
363 assert($this->isInitialEdit());
364 assert($this->selected);
366 $this->tokens['PAGE_SOURCE'] = $this->_content;
367 return $this->output('viewsource', _("View Source: %s"));
370 function updateLock() {
371 if ((bool)$this->page->get('locked') == (bool)$this->locked)
372 return false; // Not changed.
374 if (!$this->user->isAdmin()) {
375 // FIXME: some sort of message
376 return false; // not allowed.
379 $this->page->set('locked', (bool)$this->locked);
380 $this->tokens['LOCK_CHANGED_MSG']
381 = $this->locked ? _("Page now locked.") : _("Page now unlocked.");
383 return true; // lock changed.
386 function savePage () {
387 $request = &$this->request;
389 if ($this->isUnchanged()) {
390 // Allow admin lock/unlock even if
391 // no text changes were made.
392 if ($this->updateLock()) {
393 $dbi = $request->getDbh();
396 // Save failed. No changes made.
397 $this->_redirectToBrowsePage();
398 // user will probably not see the rest of this...
399 include_once('lib/display.php');
400 // force browse of current version:
401 $request->setArg('version', false);
402 displayPage($request, 'nochanges');
406 $page = &$this->page;
408 // Include any meta-data from original page version which
409 // has not been explicitly updated.
410 // (Except don't propagate pgsrc_version --- moot for now,
411 // because at present it never gets into the db...)
412 $meta = $this->selected->getMetaData();
413 unset($meta['pgsrc_version']);
414 $meta = array_merge($meta, $this->meta);
417 $this->_content = $this->getContent();
418 $newrevision = $page->save($this->_content, $this->_currentVersion + 1, $meta);
419 if (!isa($newrevision, 'wikidb_pagerevision')) {
420 // Save failed. (Concurrent updates).
424 // New contents successfully saved...
427 // Clean out archived versions of this page.
428 include_once('lib/ArchiveCleaner.php');
429 $cleaner = new ArchiveCleaner($GLOBALS['ExpireParams']);
430 $cleaner->cleanPageRevisions($page);
432 /* generate notification emails done in WikiDB::save to catch all direct calls
435 $dbi = $request->getDbh();
436 $warnings = $dbi->GenericWarnings();
440 if (empty($warnings) && ! $WikiTheme->getImageURL('signature')) {
441 // Do redirect to browse page if no signature has
442 // been defined. In this case, the user will most
443 // likely not see the rest of the HTML we generate
445 $this->_redirectToBrowsePage();
448 // Force browse of current page version.
449 $request->setArg('version', false);
450 //$request->setArg('action', false);
452 $template = Template('savepage', $this->tokens);
453 $template->replace('CONTENT', $newrevision->getTransformedContent());
454 if (!empty($warnings))
455 $template->replace('WARNINGS', $warnings);
457 $pagelink = WikiLink($page);
459 GeneratePage($template, fmt("Saved: %s", $pagelink), $newrevision);
463 function isConcurrentUpdate () {
464 assert($this->current->getVersion() >= $this->_currentVersion);
465 return $this->current->getVersion() != $this->_currentVersion;
468 function canEdit () {
469 return !$this->page->get('locked') || $this->user->isAdmin();
472 function isInitialEdit () {
473 return $this->_initialEdit;
476 function isUnchanged () {
477 $current = &$this->current;
479 if ($this->meta['markup'] != $current->get('markup'))
482 return $this->_content == $current->getPackedContent();
485 function getPreview () {
486 include_once('lib/PageType.php');
487 $this->_content = $this->getContent();
488 return new TransformedText($this->page, $this->_content, $this->meta);
491 // possibly convert HTMLAREA content back to Wiki markup
492 function getContent () {
494 $xml_output = Edit_HtmlArea_ConvertAfter($this->_content);
495 $this->_content = join("",$xml_output->_content);
496 return $this->_content;
498 return $this->_content;
502 function getLockedMessage () {
504 HTML(HTML::h2(_("Page Locked")),
505 HTML::p(_("This page has been locked by the administrator so your changes can not be saved.")),
506 HTML::p(_("(Copy your changes to the clipboard. You can try editing a different page or save your text in a text editor.)")),
507 HTML::p(_("Sorry for the inconvenience.")));
510 function getConflictMessage ($unresolved = false) {
512 xgettext only knows about c/c++ line-continuation strings
513 it does not know about php's dot operator.
514 We want to translate this entire paragraph as one string, of course.
517 //$re_edit_link = Button('edit', _("Edit the new version"), $this->page);
520 $message = HTML::p(fmt("Some of the changes could not automatically be combined. Please look for sections beginning with '%s', and ending with '%s'. You will need to edit those sections by hand before you click Save.",
521 "<<<<<<< ". _("Your version"),
522 ">>>>>>> ". _("Other version")));
524 $message = HTML::p(_("Please check it through before saving."));
528 /*$steps = HTML::ol(HTML::li(_("Copy your changes to the clipboard or to another temporary place (e.g. text editor).")),
529 HTML::li(fmt("%s of the page. You should now see the most current version of the page. Your changes are no longer there.",
531 HTML::li(_("Make changes to the file again. Paste your additions from the clipboard (or text editor).")),
532 HTML::li(_("Save your updated changes.")));
535 HTML(HTML::h2(_("Conflicting Edits!")),
536 HTML::p(_("In the time since you started editing this page, another user has saved a new version of it.")),
537 HTML::p(_("Your changes can not be saved as they are, since doing so would overwrite the other author's changes. So, your changes and those of the other author have been combined. The result is shown below.")),
542 function getTextArea () {
543 $request = &$this->request;
545 // wrap=virtual is not HTML4, but without it NS4 doesn't wrap
547 $readonly = ! $this->canEdit(); // || $this->isConcurrentUpdate();
549 $html = $this->getPreview();
550 $this->_wikicontent = $this->_content;
551 $this->_content = $html->asXML();
554 /** <textarea wrap="virtual"> is not valid xhtml but Netscape 4 requires it
555 * to wrap long lines.
557 $textarea = HTML::textarea(array('class' => 'wikiedit',
558 'name' => 'edit[content]',
559 'id' => 'edit[content]',
560 'rows' => $request->getPref('editHeight'),
561 'cols' => $request->getPref('editWidth'),
562 'readonly' => (bool) $readonly),
565 $textarea->setAttr('wrap','virtual');
567 return Edit_HtmlArea_Textarea($textarea,$this->_wikicontent,'edit[content]');
572 function getFormElements () {
573 $request = &$this->request;
574 $page = &$this->page;
577 $h = array('action' => 'edit',
578 'pagename' => $page->getName(),
579 'version' => $this->version,
580 'edit[pagetype]' => $this->meta['pagetype'],
581 'edit[current_version]' => $this->_currentVersion);
583 $el['HIDDEN_INPUTS'] = HiddenInputs($h);
584 $el['EDIT_TEXTAREA'] = $this->getTextArea();
586 = HTML::input(array('type' => 'text',
587 'class' => 'wikitext',
588 'name' => 'edit[summary]',
591 'value' => $this->meta['summary']));
593 = HTML::input(array('type' => 'checkbox',
594 'name' => 'edit[minor_edit]',
595 'checked' => (bool) $this->meta['is_minor_edit']));
597 = HTML::input(array('type' => 'checkbox',
598 'name' => 'edit[markup]',
600 'checked' => $this->meta['markup'] < 2.0,
601 'id' => 'useOldMarkup',
602 'onclick' => 'showOldMarkupRules(this.checked)'));
605 = HTML::input(array('type' => 'checkbox',
606 'name' => 'edit[locked]',
607 'disabled' => (bool) !$this->user->isadmin(),
608 'checked' => (bool) $this->locked));
610 $el['PREVIEW_B'] = Button('submit:edit[preview]', _("Preview"),
613 //if (!$this->isConcurrentUpdate() && $this->canEdit())
614 $el['SAVE_B'] = Button('submit:edit[save]', _("Save"), 'wikiaction');
616 $el['IS_CURRENT'] = $this->version == $this->current->getVersion();
621 function _redirectToBrowsePage() {
622 $this->request->redirect(WikiURL($this->page, false, 'absolute_url'));
626 function _restoreState () {
627 $request = &$this->request;
629 $posted = $request->getArg('edit');
630 $request->setArg('edit', false);
632 if (!$posted || !$request->isPost()
633 || $request->getArg('action') != 'edit')
636 if (!isset($posted['content']) || !is_string($posted['content']))
638 $this->_content = preg_replace('/[ \t\r]+\n/', "\n",
639 rtrim($posted['content']));
640 $this->_content = $this->getContent();
642 $this->_currentVersion = (int) $posted['current_version'];
644 if ($this->_currentVersion < 0)
646 if ($this->_currentVersion > $this->current->getVersion())
647 return false; // FIXME: some kind of warning?
649 $is_old_markup = !empty($posted['markup']) && $posted['markup'] == 'old';
650 $meta['markup'] = $is_old_markup ? false : 2.0;
651 $meta['summary'] = trim(substr($posted['summary'], 0, 256));
652 $meta['is_minor_edit'] = !empty($posted['minor_edit']);
653 $meta['pagetype'] = !empty($posted['pagetype']) ? $posted['pagetype'] : false;
654 $this->meta = array_merge($this->meta, $meta);
655 $this->locked = !empty($posted['locked']);
657 if (!empty($posted['preview']))
658 $this->editaction = 'preview';
659 elseif (!empty($posted['save']))
660 $this->editaction = 'save';
662 $this->editaction = 'edit';
667 function _initializeState () {
668 $request = &$this->request;
669 $current = &$this->current;
670 $selected = &$this->selected;
671 $user = &$this->user;
674 NoSuchRevision($request, $this->page, $this->version); // noreturn
676 $this->_currentVersion = $current->getVersion();
677 $this->_content = $selected->getPackedContent();
679 $this->meta['summary'] = '';
680 $this->locked = $this->page->get('locked');
682 // If author same as previous author, default minor_edit to on.
683 $age = $this->meta['mtime'] - $current->get('mtime');
684 $this->meta['is_minor_edit'] = ( $age < MINOR_EDIT_TIMEOUT
685 && $current->get('author') == $user->getId()
688 // Default for new pages is new-style markup.
689 if ($selected->hasDefaultContents())
690 $is_new_markup = true;
692 $is_new_markup = $selected->get('markup') >= 2.0;
694 $this->meta['markup'] = $is_new_markup ? 2.0: false;
695 $this->meta['pagetype'] = $selected->get('pagetype');
696 $this->editaction = 'edit';
700 class LoadFileConflictPageEditor
703 function editPage ($saveFailed = true) {
704 $tokens = &$this->tokens;
706 if (!$this->canEdit()) {
707 if ($this->isInitialEdit())
708 return $this->viewSource();
709 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
711 elseif ($this->editaction == 'save') {
712 if ($this->savePage())
713 return true; // Page saved.
717 if ($saveFailed || $this->isConcurrentUpdate())
719 // Get the text of the original page, and the two conflicting edits
720 // The diff class takes arrays as input. So retrieve content as
721 // an array, or convert it as necesary.
722 $orig = $this->page->getRevision($this->_currentVersion);
723 $this_content = explode("\n", $this->_content);
724 $other_content = $this->current->getContent();
725 include_once("lib/diff.php");
726 $diff2 = new Diff($other_content, $this_content);
727 $context_lines = max(4, count($other_content) + 1,
728 count($this_content) + 1);
729 $fmt = new BlockDiffFormatter($context_lines);
731 $this->_content = $fmt->format($diff2);
732 // FIXME: integrate this into class BlockDiffFormatter
733 $this->_content = str_replace(">>>>>>>\n<<<<<<<\n", "=======\n",
735 $this->_content = str_replace("<<<<<<<\n>>>>>>>\n", "=======\n",
738 $this->_currentVersion = $this->current->getVersion();
739 $this->version = $this->_currentVersion;
740 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage();
743 if ($this->editaction == 'preview')
744 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
746 // FIXME: NOT_CURRENT_MESSAGE?
748 $tokens = array_merge($tokens, $this->getFormElements());
750 return $this->output('editpage', _("Merge and Edit: %s"));
751 // FIXME: this doesn't display
754 function output ($template, $title_fs) {
755 $selected = &$this->selected;
756 $current = &$this->current;
758 if ($selected && $selected->getVersion() != $current->getVersion()) {
760 $pagelink = WikiLink($selected);
764 $pagelink = WikiLink($this->page);
767 $title = new FormattedText ($title_fs, $pagelink);
768 $template = Template($template, $this->tokens);
770 //GeneratePage($template, $title, $rev);
774 function getConflictMessage () {
775 $message = HTML(HTML::p(fmt("Some of the changes could not automatically be combined. Please look for sections beginning with '%s', and ending with '%s'. You will need to edit those sections by hand before you click Save.",
778 HTML::p(_("Please check it through before saving."))));
784 $Log: not supported by cvs2svn $
785 Revision 1.76 2004/11/15 15:37:34 rurban
787 don't use document.write for replace, otherwise self.opener is not defined.
789 Revision 1.75 2004/09/16 08:00:52 rurban
792 Revision 1.74 2004/07/03 07:36:28 rurban
793 do not get unneccessary content
795 Revision 1.73 2004/06/16 21:23:44 rurban
796 fixed non-object fatal #215
798 Revision 1.72 2004/06/14 11:31:37 rurban
799 renamed global $Theme to $WikiTheme (gforge nameclash)
800 inherit PageList default options from PageList
801 default sortby=pagename
802 use options in PageList_Selectable (limit, sortby, ...)
803 added action revert, with button at action=diff
804 added option regex to WikiAdminSearchReplace
806 Revision 1.71 2004/06/03 18:06:29 rurban
807 fix file locking issues (only needed on write)
808 fixed immediate LANG and THEME in-session updates if not stored in prefs
809 advanced editpage toolbars (search & replace broken)
811 Revision 1.70 2004/06/02 20:47:47 rurban
812 dont use the wikiaction class
814 Revision 1.69 2004/06/02 10:17:56 rurban
815 integrated search/replace into toolbar
816 added save+preview buttons
818 Revision 1.68 2004/06/01 15:28:00 rurban
819 AdminUser only ADMIN_USER not member of Administrators
820 some RateIt improvements by dfrankow
823 Revision _1.6 2004/05/26 15:48:00 syilek
824 fixed problem with creating page with slashes from one true page
826 Revision _1.5 2004/05/25 16:51:53 syilek
827 added ability to create a page from the category page and not have to edit it
829 Revision 1.67 2004/05/27 17:49:06 rurban
830 renamed DB_Session to DbSession (in CVS also)
831 added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
832 remove leading slash in error message
833 added force_unlock parameter to File_Passwd (no return on stale locks)
834 fixed adodb session AffectedRows
835 added FileFinder helpers to unify local filenames and DATA_PATH names
836 editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
838 Revision 1.66 2004/04/29 23:25:12 rurban
839 re-ordered locale init (as in 1.3.9)
840 fixed loadfile with subpages, and merge/restore anyway
843 Revision 1.65 2004/04/18 01:11:52 rurban
844 more numeric pagename fixes.
845 fixed action=upload with merge conflict warnings.
846 charset changed from constant to global (dynamic utf-8 switching)
848 Revision 1.64 2004/04/06 19:48:56 rurban
849 temp workaround for action=edit AddComment form
851 Revision 1.63 2004/03/24 19:39:02 rurban
852 php5 workaround code (plus some interim debugging code in XmlElement)
853 php5 doesn't work yet with the current XmlElement class constructors,
854 WikiUserNew does work better than php4.
855 rewrote WikiUserNew user upgrading to ease php5 update
856 fixed pref handling in WikiUserNew
857 added Email Notification
858 added simple Email verification
859 removed emailVerify userpref subclass: just a email property
860 changed pref binary storage layout: numarray => hash of non default values
861 print optimize message only if really done.
862 forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
863 prefs should be stored in db or homepage, besides the current session.
865 Revision 1.62 2004/03/17 18:41:05 rurban
866 initial_content and template support for CreatePage
868 Revision 1.61 2004/03/12 20:59:17 rurban
869 important cookie fix by Konstantin Zadorozhny
870 new editpage feature: JS_SEARCHREPLACE
872 Revision 1.60 2004/02/15 21:34:37 rurban
873 PageList enhanced and improved.
874 fixed new WikiAdmin... plugins
875 editpage, Theme with exp. htmlarea framework
876 (htmlarea yet committed, this is really questionable)
877 WikiUser... code with better session handling for prefs
878 enhanced UserPreferences (again)
879 RecentChanges for show_deleted: how should pages be deleted then?
881 Revision 1.59 2003/12/07 20:35:26 carstenklapp
882 Bugfix: Concurrent updates broken since after 1.3.4 release: Fatal
883 error: Call to undefined function: gettransformedcontent() in
884 /home/groups/p/ph/phpwiki/htdocs/phpwiki2/lib/editpage.php on line
887 Revision 1.58 2003/03/10 18:25:22 dairiki
888 Bug/typo fix. If you use the edit page to un/lock a page, it
889 failed with: Fatal error: Call to a member function on a
890 non-object in editpage.php on line 136
892 Revision 1.57 2003/02/26 03:40:22 dairiki
893 New action=create. Essentially the same as action=edit, except that if the
894 page already exists, it falls back to action=browse.
896 This is for use in the "question mark" links for unknown wiki words
897 to avoid problems and confusion when following links from stale pages.
898 (If the "unknown page" has been created in the interim, the user probably
899 wants to view the page before editing it.)
901 Revision 1.56 2003/02/21 18:07:14 dairiki
902 Minor, nitpicky, currently inconsequential changes.
904 Revision 1.55 2003/02/21 04:10:58 dairiki
905 Fixes for new cached markup.
906 Some minor code cleanups.
908 Revision 1.54 2003/02/16 19:47:16 dairiki
909 Update WikiDB timestamp when editing or deleting pages.
911 Revision 1.53 2003/02/15 23:20:27 dairiki
912 Redirect back to browse current version of page upon save,
913 even when no changes were made.
915 Revision 1.52 2003/01/03 22:22:00 carstenklapp
916 Minor adjustments to diff block markers ("<<<<<<<"). Source reformatting.
918 Revision 1.51 2003/01/03 02:43:26 carstenklapp
919 New class LoadFileConflictPageEditor, for merging / comparing a loaded
920 pgsrc file with an existing page.
928 // c-hanging-comment-ender-p: nil
929 // indent-tabs-mode: nil