2 rcs_id('$Id: editpage.php,v 1.76 2004-11-15 15:37:34 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=\"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 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(
310 'title'=>_("Undo Search & Replace"),
311 'disabled'=>"disabled",
313 'onfocus' =>"if(this.blur && undo_buffer_index==0) this.blur()",
314 'onclick' =>"do_undo()")),
315 HTML::input(array('type'=>"image",
318 'title'=>_("Search & Replace"),
319 'onclick'=>"replace()")));
320 /*$sr_js = '<input type="image" class="toolbar" id="sr_undo" src="'.$undo_d_btn.'" title="'._("Undo Search & Replace").'" disabled="disabled" value="Undo" onfocus="if(this.blur && undo_buffer_index==0) this.blur()" onclick="do_undo()">'
321 // . '<input type="image" class="toolbar" src="'.$redo_btn.'" title="'._("Snap").'" onclick="speich()">'
322 . '<input type="image" class="toolbar" src="'.$sr_btn.'" title="'._("Search & Replace").'" onclick="replace()">';
323 $toolbar.='document.writeln("'.addslashes($sr_js).'");'."\n";
325 } else $sr_html = '';
327 // Button to generate pagenames, display in extra window as pulldown and insert
328 // Button to generate plugins, display in extra window as pulldown and insert
329 // Button to generate categories, display in extra window as pulldown and insert
330 $toolbar_end = "document.writeln(\"</div>\");";
331 // don't use document.write for replace, otherwise self.opener is not defined.
332 return HTML(Javascript($toolbar),
334 Javascript($toolbar_end));
337 function output ($template, $title_fs) {
339 $selected = &$this->selected;
340 $current = &$this->current;
342 if ($selected && $selected->getVersion() != $current->getVersion()) {
344 $pagelink = WikiLink($selected);
348 $pagelink = WikiLink($this->page);
352 $title = new FormattedText ($title_fs, $pagelink);
353 if ($template == 'editpage' and USE_HTMLAREA) {
354 $WikiTheme->addMoreHeaders(Edit_HtmlArea_Head());
355 //$tokens['PAGE_SOURCE'] = Edit_HtmlArea_ConvertBefore($this->_content);
357 $template = Template($template, $this->tokens);
358 GeneratePage($template, $title, $rev);
363 function viewSource () {
364 assert($this->isInitialEdit());
365 assert($this->selected);
367 $this->tokens['PAGE_SOURCE'] = $this->_content;
368 return $this->output('viewsource', _("View Source: %s"));
371 function updateLock() {
372 if ((bool)$this->page->get('locked') == (bool)$this->locked)
373 return false; // Not changed.
375 if (!$this->user->isAdmin()) {
376 // FIXME: some sort of message
377 return false; // not allowed.
380 $this->page->set('locked', (bool)$this->locked);
381 $this->tokens['LOCK_CHANGED_MSG']
382 = $this->locked ? _("Page now locked.") : _("Page now unlocked.");
384 return true; // lock changed.
387 function savePage () {
388 $request = &$this->request;
390 if ($this->isUnchanged()) {
391 // Allow admin lock/unlock even if
392 // no text changes were made.
393 if ($this->updateLock()) {
394 $dbi = $request->getDbh();
397 // Save failed. No changes made.
398 $this->_redirectToBrowsePage();
399 // user will probably not see the rest of this...
400 include_once('lib/display.php');
401 // force browse of current version:
402 $request->setArg('version', false);
403 displayPage($request, 'nochanges');
407 $page = &$this->page;
409 // Include any meta-data from original page version which
410 // has not been explicitly updated.
411 // (Except don't propagate pgsrc_version --- moot for now,
412 // because at present it never gets into the db...)
413 $meta = $this->selected->getMetaData();
414 unset($meta['pgsrc_version']);
415 $meta = array_merge($meta, $this->meta);
418 $this->_content = $this->getContent();
419 $newrevision = $page->save($this->_content, $this->_currentVersion + 1, $meta);
420 if (!isa($newrevision, 'wikidb_pagerevision')) {
421 // Save failed. (Concurrent updates).
425 // New contents successfully saved...
428 // Clean out archived versions of this page.
429 include_once('lib/ArchiveCleaner.php');
430 $cleaner = new ArchiveCleaner($GLOBALS['ExpireParams']);
431 $cleaner->cleanPageRevisions($page);
433 /* generate notification emails done in WikiDB::save to catch all direct calls
436 $dbi = $request->getDbh();
437 $warnings = $dbi->GenericWarnings();
441 if (empty($warnings) && ! $WikiTheme->getImageURL('signature')) {
442 // Do redirect to browse page if no signature has
443 // been defined. In this case, the user will most
444 // likely not see the rest of the HTML we generate
446 $this->_redirectToBrowsePage();
449 // Force browse of current page version.
450 $request->setArg('version', false);
451 //$request->setArg('action', false);
453 $template = Template('savepage', $this->tokens);
454 $template->replace('CONTENT', $newrevision->getTransformedContent());
455 if (!empty($warnings))
456 $template->replace('WARNINGS', $warnings);
458 $pagelink = WikiLink($page);
460 GeneratePage($template, fmt("Saved: %s", $pagelink), $newrevision);
464 function isConcurrentUpdate () {
465 assert($this->current->getVersion() >= $this->_currentVersion);
466 return $this->current->getVersion() != $this->_currentVersion;
469 function canEdit () {
470 return !$this->page->get('locked') || $this->user->isAdmin();
473 function isInitialEdit () {
474 return $this->_initialEdit;
477 function isUnchanged () {
478 $current = &$this->current;
480 if ($this->meta['markup'] != $current->get('markup'))
483 return $this->_content == $current->getPackedContent();
486 function getPreview () {
487 include_once('lib/PageType.php');
488 $this->_content = $this->getContent();
489 return new TransformedText($this->page, $this->_content, $this->meta);
492 // possibly convert HTMLAREA content back to Wiki markup
493 function getContent () {
495 $xml_output = Edit_HtmlArea_ConvertAfter($this->_content);
496 $this->_content = join("",$xml_output->_content);
497 return $this->_content;
499 return $this->_content;
503 function getLockedMessage () {
505 HTML(HTML::h2(_("Page Locked")),
506 HTML::p(_("This page has been locked by the administrator so your changes can not be saved.")),
507 HTML::p(_("(Copy your changes to the clipboard. You can try editing a different page or save your text in a text editor.)")),
508 HTML::p(_("Sorry for the inconvenience.")));
511 function getConflictMessage ($unresolved = false) {
513 xgettext only knows about c/c++ line-continuation strings
514 it does not know about php's dot operator.
515 We want to translate this entire paragraph as one string, of course.
518 //$re_edit_link = Button('edit', _("Edit the new version"), $this->page);
521 $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.",
522 "<<<<<<< ". _("Your version"),
523 ">>>>>>> ". _("Other version")));
525 $message = HTML::p(_("Please check it through before saving."));
529 /*$steps = HTML::ol(HTML::li(_("Copy your changes to the clipboard or to another temporary place (e.g. text editor).")),
530 HTML::li(fmt("%s of the page. You should now see the most current version of the page. Your changes are no longer there.",
532 HTML::li(_("Make changes to the file again. Paste your additions from the clipboard (or text editor).")),
533 HTML::li(_("Save your updated changes.")));
536 HTML(HTML::h2(_("Conflicting Edits!")),
537 HTML::p(_("In the time since you started editing this page, another user has saved a new version of it.")),
538 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.")),
543 function getTextArea () {
544 $request = &$this->request;
546 // wrap=virtual is not HTML4, but without it NS4 doesn't wrap
548 $readonly = ! $this->canEdit(); // || $this->isConcurrentUpdate();
550 $html = $this->getPreview();
551 $this->_wikicontent = $this->_content;
552 $this->_content = $html->asXML();
555 /** <textarea wrap="virtual"> is not valid xhtml but Netscape 4 requires it
556 * to wrap long lines.
558 $textarea = HTML::textarea(array('class' => 'wikiedit',
559 'name' => 'edit[content]',
560 'id' => 'edit[content]',
561 'rows' => $request->getPref('editHeight'),
562 'cols' => $request->getPref('editWidth'),
563 'readonly' => (bool) $readonly),
566 $textarea->setAttr('wrap','virtual');
568 return Edit_HtmlArea_Textarea($textarea,$this->_wikicontent,'edit[content]');
573 function getFormElements () {
574 $request = &$this->request;
575 $page = &$this->page;
578 $h = array('action' => 'edit',
579 'pagename' => $page->getName(),
580 'version' => $this->version,
581 'edit[pagetype]' => $this->meta['pagetype'],
582 'edit[current_version]' => $this->_currentVersion);
584 $el['HIDDEN_INPUTS'] = HiddenInputs($h);
585 $el['EDIT_TEXTAREA'] = $this->getTextArea();
587 = HTML::input(array('type' => 'text',
588 'class' => 'wikitext',
589 'name' => 'edit[summary]',
592 'value' => $this->meta['summary']));
594 = HTML::input(array('type' => 'checkbox',
595 'name' => 'edit[minor_edit]',
596 'checked' => (bool) $this->meta['is_minor_edit']));
598 = HTML::input(array('type' => 'checkbox',
599 'name' => 'edit[markup]',
601 'checked' => $this->meta['markup'] < 2.0,
602 'id' => 'useOldMarkup',
603 'onclick' => 'showOldMarkupRules(this.checked)'));
606 = HTML::input(array('type' => 'checkbox',
607 'name' => 'edit[locked]',
608 'disabled' => (bool) !$this->user->isadmin(),
609 'checked' => (bool) $this->locked));
611 $el['PREVIEW_B'] = Button('submit:edit[preview]', _("Preview"),
614 //if (!$this->isConcurrentUpdate() && $this->canEdit())
615 $el['SAVE_B'] = Button('submit:edit[save]', _("Save"), 'wikiaction');
617 $el['IS_CURRENT'] = $this->version == $this->current->getVersion();
622 function _redirectToBrowsePage() {
623 $this->request->redirect(WikiURL($this->page, false, 'absolute_url'));
627 function _restoreState () {
628 $request = &$this->request;
630 $posted = $request->getArg('edit');
631 $request->setArg('edit', false);
633 if (!$posted || !$request->isPost()
634 || $request->getArg('action') != 'edit')
637 if (!isset($posted['content']) || !is_string($posted['content']))
639 $this->_content = preg_replace('/[ \t\r]+\n/', "\n",
640 rtrim($posted['content']));
641 $this->_content = $this->getContent();
643 $this->_currentVersion = (int) $posted['current_version'];
645 if ($this->_currentVersion < 0)
647 if ($this->_currentVersion > $this->current->getVersion())
648 return false; // FIXME: some kind of warning?
650 $is_old_markup = !empty($posted['markup']) && $posted['markup'] == 'old';
651 $meta['markup'] = $is_old_markup ? false : 2.0;
652 $meta['summary'] = trim(substr($posted['summary'], 0, 256));
653 $meta['is_minor_edit'] = !empty($posted['minor_edit']);
654 $meta['pagetype'] = !empty($posted['pagetype']) ? $posted['pagetype'] : false;
655 $this->meta = array_merge($this->meta, $meta);
656 $this->locked = !empty($posted['locked']);
658 if (!empty($posted['preview']))
659 $this->editaction = 'preview';
660 elseif (!empty($posted['save']))
661 $this->editaction = 'save';
663 $this->editaction = 'edit';
668 function _initializeState () {
669 $request = &$this->request;
670 $current = &$this->current;
671 $selected = &$this->selected;
672 $user = &$this->user;
675 NoSuchRevision($request, $this->page, $this->version); // noreturn
677 $this->_currentVersion = $current->getVersion();
678 $this->_content = $selected->getPackedContent();
680 $this->meta['summary'] = '';
681 $this->locked = $this->page->get('locked');
683 // If author same as previous author, default minor_edit to on.
684 $age = $this->meta['mtime'] - $current->get('mtime');
685 $this->meta['is_minor_edit'] = ( $age < MINOR_EDIT_TIMEOUT
686 && $current->get('author') == $user->getId()
689 // Default for new pages is new-style markup.
690 if ($selected->hasDefaultContents())
691 $is_new_markup = true;
693 $is_new_markup = $selected->get('markup') >= 2.0;
695 $this->meta['markup'] = $is_new_markup ? 2.0: false;
696 $this->meta['pagetype'] = $selected->get('pagetype');
697 $this->editaction = 'edit';
701 class LoadFileConflictPageEditor
704 function editPage ($saveFailed = true) {
705 $tokens = &$this->tokens;
707 if (!$this->canEdit()) {
708 if ($this->isInitialEdit())
709 return $this->viewSource();
710 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
712 elseif ($this->editaction == 'save') {
713 if ($this->savePage())
714 return true; // Page saved.
718 if ($saveFailed || $this->isConcurrentUpdate())
720 // Get the text of the original page, and the two conflicting edits
721 // The diff class takes arrays as input. So retrieve content as
722 // an array, or convert it as necesary.
723 $orig = $this->page->getRevision($this->_currentVersion);
724 $this_content = explode("\n", $this->_content);
725 $other_content = $this->current->getContent();
726 include_once("lib/diff.php");
727 $diff2 = new Diff($other_content, $this_content);
728 $context_lines = max(4, count($other_content) + 1,
729 count($this_content) + 1);
730 $fmt = new BlockDiffFormatter($context_lines);
732 $this->_content = $fmt->format($diff2);
733 // FIXME: integrate this into class BlockDiffFormatter
734 $this->_content = str_replace(">>>>>>>\n<<<<<<<\n", "=======\n",
736 $this->_content = str_replace("<<<<<<<\n>>>>>>>\n", "=======\n",
739 $this->_currentVersion = $this->current->getVersion();
740 $this->version = $this->_currentVersion;
741 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage();
744 if ($this->editaction == 'preview')
745 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
747 // FIXME: NOT_CURRENT_MESSAGE?
749 $tokens = array_merge($tokens, $this->getFormElements());
751 return $this->output('editpage', _("Merge and Edit: %s"));
752 // FIXME: this doesn't display
755 function output ($template, $title_fs) {
756 $selected = &$this->selected;
757 $current = &$this->current;
759 if ($selected && $selected->getVersion() != $current->getVersion()) {
761 $pagelink = WikiLink($selected);
765 $pagelink = WikiLink($this->page);
768 $title = new FormattedText ($title_fs, $pagelink);
769 $template = Template($template, $this->tokens);
771 //GeneratePage($template, $title, $rev);
775 function getConflictMessage () {
776 $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.",
779 HTML::p(_("Please check it through before saving."))));
785 $Log: not supported by cvs2svn $
786 Revision 1.75 2004/09/16 08:00:52 rurban
789 Revision 1.74 2004/07/03 07:36:28 rurban
790 do not get unneccessary content
792 Revision 1.73 2004/06/16 21:23:44 rurban
793 fixed non-object fatal #215
795 Revision 1.72 2004/06/14 11:31:37 rurban
796 renamed global $Theme to $WikiTheme (gforge nameclash)
797 inherit PageList default options from PageList
798 default sortby=pagename
799 use options in PageList_Selectable (limit, sortby, ...)
800 added action revert, with button at action=diff
801 added option regex to WikiAdminSearchReplace
803 Revision 1.71 2004/06/03 18:06:29 rurban
804 fix file locking issues (only needed on write)
805 fixed immediate LANG and THEME in-session updates if not stored in prefs
806 advanced editpage toolbars (search & replace broken)
808 Revision 1.70 2004/06/02 20:47:47 rurban
809 dont use the wikiaction class
811 Revision 1.69 2004/06/02 10:17:56 rurban
812 integrated search/replace into toolbar
813 added save+preview buttons
815 Revision 1.68 2004/06/01 15:28:00 rurban
816 AdminUser only ADMIN_USER not member of Administrators
817 some RateIt improvements by dfrankow
820 Revision _1.6 2004/05/26 15:48:00 syilek
821 fixed problem with creating page with slashes from one true page
823 Revision _1.5 2004/05/25 16:51:53 syilek
824 added ability to create a page from the category page and not have to edit it
826 Revision 1.67 2004/05/27 17:49:06 rurban
827 renamed DB_Session to DbSession (in CVS also)
828 added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
829 remove leading slash in error message
830 added force_unlock parameter to File_Passwd (no return on stale locks)
831 fixed adodb session AffectedRows
832 added FileFinder helpers to unify local filenames and DATA_PATH names
833 editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
835 Revision 1.66 2004/04/29 23:25:12 rurban
836 re-ordered locale init (as in 1.3.9)
837 fixed loadfile with subpages, and merge/restore anyway
840 Revision 1.65 2004/04/18 01:11:52 rurban
841 more numeric pagename fixes.
842 fixed action=upload with merge conflict warnings.
843 charset changed from constant to global (dynamic utf-8 switching)
845 Revision 1.64 2004/04/06 19:48:56 rurban
846 temp workaround for action=edit AddComment form
848 Revision 1.63 2004/03/24 19:39:02 rurban
849 php5 workaround code (plus some interim debugging code in XmlElement)
850 php5 doesn't work yet with the current XmlElement class constructors,
851 WikiUserNew does work better than php4.
852 rewrote WikiUserNew user upgrading to ease php5 update
853 fixed pref handling in WikiUserNew
854 added Email Notification
855 added simple Email verification
856 removed emailVerify userpref subclass: just a email property
857 changed pref binary storage layout: numarray => hash of non default values
858 print optimize message only if really done.
859 forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
860 prefs should be stored in db or homepage, besides the current session.
862 Revision 1.62 2004/03/17 18:41:05 rurban
863 initial_content and template support for CreatePage
865 Revision 1.61 2004/03/12 20:59:17 rurban
866 important cookie fix by Konstantin Zadorozhny
867 new editpage feature: JS_SEARCHREPLACE
869 Revision 1.60 2004/02/15 21:34:37 rurban
870 PageList enhanced and improved.
871 fixed new WikiAdmin... plugins
872 editpage, Theme with exp. htmlarea framework
873 (htmlarea yet committed, this is really questionable)
874 WikiUser... code with better session handling for prefs
875 enhanced UserPreferences (again)
876 RecentChanges for show_deleted: how should pages be deleted then?
878 Revision 1.59 2003/12/07 20:35:26 carstenklapp
879 Bugfix: Concurrent updates broken since after 1.3.4 release: Fatal
880 error: Call to undefined function: gettransformedcontent() in
881 /home/groups/p/ph/phpwiki/htdocs/phpwiki2/lib/editpage.php on line
884 Revision 1.58 2003/03/10 18:25:22 dairiki
885 Bug/typo fix. If you use the edit page to un/lock a page, it
886 failed with: Fatal error: Call to a member function on a
887 non-object in editpage.php on line 136
889 Revision 1.57 2003/02/26 03:40:22 dairiki
890 New action=create. Essentially the same as action=edit, except that if the
891 page already exists, it falls back to action=browse.
893 This is for use in the "question mark" links for unknown wiki words
894 to avoid problems and confusion when following links from stale pages.
895 (If the "unknown page" has been created in the interim, the user probably
896 wants to view the page before editing it.)
898 Revision 1.56 2003/02/21 18:07:14 dairiki
899 Minor, nitpicky, currently inconsequential changes.
901 Revision 1.55 2003/02/21 04:10:58 dairiki
902 Fixes for new cached markup.
903 Some minor code cleanups.
905 Revision 1.54 2003/02/16 19:47:16 dairiki
906 Update WikiDB timestamp when editing or deleting pages.
908 Revision 1.53 2003/02/15 23:20:27 dairiki
909 Redirect back to browse current version of page upon save,
910 even when no changes were made.
912 Revision 1.52 2003/01/03 22:22:00 carstenklapp
913 Minor adjustments to diff block markers ("<<<<<<<"). Source reformatting.
915 Revision 1.51 2003/01/03 02:43:26 carstenklapp
916 New class LoadFileConflictPageEditor, for merging / comparing a loaded
917 pgsrc file with an existing page.
925 // c-hanging-comment-ender-p: nil
926 // indent-tabs-mode: nil