2 rcs_id('$Id: editpage.php,v 1.98 2005-10-10 19:37:04 rurban Exp $');
4 require_once('lib/Template.php');
6 // ENABLE_WYSIWYG - Support for some WYSIWYG HTML Editor (tinymce or htmlarea3)
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
10 // might prefer HTML markup.
11 // TODO: Change from constant to user preference variable
12 // (checkbox setting or edit click as in gmail),
13 // when HtmlParser is finished.
15 if (!defined('USE_HTMLAREA')) define('USE_HTMLAREA', false);
16 if (USE_TINYMCE) require_once('lib/tinymce.php');
17 else if (USE_HTMLAREA) require_once('lib/htmlarea.php');
19 if (ENABLE_CAPTCHA) require_once('lib/Captcha.php');
23 function PageEditor (&$request) {
24 $this->request = &$request;
26 $this->user = $request->getUser();
27 $this->page = $request->getPage();
29 $this->current = $this->page->getCurrentRevision(false);
31 // HACKish short circuit to browse on action=create
32 if ($request->getArg('action') == 'create') {
33 if (! $this->current->hasDefaultContents())
34 $request->redirect(WikiURL($this->page->getName())); // noreturn
38 $this->meta = array('author' => $this->user->getId(),
39 'author_id' => $this->user->getAuthenticatedId(),
42 $this->tokens = array();
44 $version = $request->getArg('version');
45 if ($version !== false) {
46 $this->selected = $this->page->getRevision($version);
47 $this->version = $version;
50 $this->version = $this->current->getVersion();
51 $this->selected = $this->page->getRevision($this->version);
54 if ($this->_restoreState()) {
55 $this->_initialEdit = false;
58 $this->_initializeState();
59 $this->_initialEdit = true;
61 // The edit request has specified some initial content from a template
62 if ( ($template = $request->getArg('template'))
63 and $request->_dbi->isWikiPage($template)) {
64 $page = $request->_dbi->getPage($template);
65 $current = $page->getCurrentRevision();
66 $this->_content = $current->getPackedContent();
67 } elseif ($initial_content = $request->getArg('initial_content')) {
68 $this->_content = $initial_content;
69 $this->_redirect_to = $request->getArg('save_and_redirect_to');
73 header("Content-Type: text/html; charset=" . $GLOBALS['charset']);
76 function editPage () {
79 $tokens = &$this->tokens;
80 $tokens['PAGE_LOCKED_MESSAGE'] = '';
81 $tokens['CONCURRENT_UPDATE_MESSAGE'] = '';
83 if (isset($this->request->args['pref']['editWidth'])
84 and ($this->request->getPref('editWidth') != $this->request->args['pref']['editWidth'])) {
85 $this->request->_prefs->set('editWidth', $this->request->args['pref']['editWidth']);
87 if (isset($this->request->args['pref']['editHeight'])
88 and ($this->request->getPref('editHeight') != $this->request->args['pref']['editHeight'])) {
89 $this->request->_prefs->set('editHeight', $this->request->args['pref']['editHeight']);
92 if (! $this->canEdit()) {
93 if ($this->isInitialEdit())
94 return $this->viewSource();
95 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
97 elseif ($this->request->getArg('save_and_redirect_to') != "") {
98 if (ENABLE_CAPTCHA && $this->captchaFailed()) {
99 $this->tokens['PAGE_LOCKED_MESSAGE'] =
100 HTML::p(HTML::h1(_("Typed in verification word mismatch ... are you a bot?")));
102 elseif ( $this->savePage()) {
104 $this->request->redirect(WikiURL($this->request->getArg('save_and_redirect_to')));
105 return true; // Page saved.
109 elseif ($this->editaction == 'save') {
110 if (ENABLE_CAPTCHA && $this->captchaFailed()) {
111 $this->tokens['PAGE_LOCKED_MESSAGE'] =
112 HTML::p(HTML::h1(_("Typed in verification word mismatch ... are you a bot?")));
114 elseif ($this->savePage()) {
115 return true; // Page saved.
121 if ($saveFailed and $this->isConcurrentUpdate())
123 // Get the text of the original page, and the two conflicting edits
124 // The diff3 class takes arrays as input. So retrieve content as
125 // an array, or convert it as necesary.
126 $orig = $this->page->getRevision($this->_currentVersion);
127 // FIXME: what if _currentVersion has be deleted?
128 $orig_content = $orig->getContent();
129 $this_content = explode("\n", $this->_content);
130 $other_content = $this->current->getContent();
131 include_once("lib/diff3.php");
132 $diff = new diff3($orig_content, $this_content, $other_content);
133 $output = $diff->merged_output(_("Your version"), _("Other version"));
134 // Set the content of the textarea to the merged diff
135 // output, and update the version
136 $this->_content = implode ("\n", $output);
137 $this->_currentVersion = $this->current->getVersion();
138 $this->version = $this->_currentVersion;
139 $unresolved = $diff->ConflictingBlocks;
140 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage($unresolved);
141 } elseif ($saveFailed) {
142 $tokens['CONCURRENT_UPDATE_MESSAGE'] =
143 HTML(HTML::h2(_("Some internal editing error")),
144 HTML::p(_("Your are probably trying to edit/create an invalid version of this page.")),
145 HTML::p(HTML::em(_("&version=-1 might help."))));
148 if ($this->editaction == 'edit_convert')
149 $tokens['PREVIEW_CONTENT'] = $this->getConvertedPreview();
150 if ($this->editaction == 'preview')
151 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
153 // FIXME: NOT_CURRENT_MESSAGE?
154 $tokens = array_merge($tokens, $this->getFormElements());
156 if (ENABLE_EDIT_TOOLBAR and !ENABLE_WYSIWYG) {
157 include_once("lib/EditToolbar.php");
158 $toolbar = new EditToolbar();
159 $tokens = array_merge($tokens, $toolbar->getTokens());
162 return $this->output('editpage', _("Edit: %s"));
165 function output ($template, $title_fs) {
167 $selected = &$this->selected;
168 $current = &$this->current;
170 if ($selected && $selected->getVersion() != $current->getVersion()) {
172 $pagelink = WikiLink($selected);
176 $pagelink = WikiLink($this->page);
179 $title = new FormattedText ($title_fs, $pagelink);
180 // not for dumphtml or viewsource
181 if (ENABLE_WYSIWYG and $template == 'editpage') {
182 $WikiTheme->addMoreHeaders(Edit_WYSIWYG_Head());
183 //$tokens['PAGE_SOURCE'] = Edit_WYSIWYG_ConvertBefore($this->_content);
185 $template = Template($template, $this->tokens);
186 GeneratePage($template, $title, $rev);
191 function viewSource () {
192 assert($this->isInitialEdit());
193 assert($this->selected);
195 $this->tokens['PAGE_SOURCE'] = $this->_content;
196 return $this->output('viewsource', _("View Source: %s"));
199 function updateLock() {
200 if ((bool)$this->page->get('locked') == (bool)$this->locked)
201 return false; // Not changed.
203 if (!$this->user->isAdmin()) {
204 // FIXME: some sort of message
205 return false; // not allowed.
208 $this->page->set('locked', (bool)$this->locked);
209 $this->tokens['LOCK_CHANGED_MSG']
210 = $this->locked ? _("Page now locked.") : _("Page now unlocked.");
212 return true; // lock changed.
215 function savePage () {
216 $request = &$this->request;
218 if ($this->isUnchanged()) {
219 // Allow admin lock/unlock even if
220 // no text changes were made.
221 if ($this->updateLock()) {
222 $dbi = $request->getDbh();
225 // Save failed. No changes made.
226 $this->_redirectToBrowsePage();
227 // user will probably not see the rest of this...
228 include_once('lib/display.php');
229 // force browse of current version:
230 $request->setArg('version', false);
231 displayPage($request, 'nochanges');
235 if ($this->isSpam()) {
238 // Save failed. No changes made.
239 $this->_redirectToBrowsePage();
240 // user will probably not see the rest of this...
241 include_once('lib/display.php');
242 // force browse of current version:
243 $request->setArg('version', false);
244 displayPage($request, 'nochanges');
249 $page = &$this->page;
251 // Include any meta-data from original page version which
252 // has not been explicitly updated.
253 // (Except don't propagate pgsrc_version --- moot for now,
254 // because at present it never gets into the db...)
255 $meta = $this->selected->getMetaData();
256 unset($meta['pgsrc_version']);
257 $meta = array_merge($meta, $this->meta);
260 $this->_content = $this->getContent();
261 $newrevision = $page->save($this->_content,
264 : $this->_currentVersion + 1,
267 if (!isa($newrevision, 'WikiDB_PageRevision')) {
268 // Save failed. (Concurrent updates).
272 // New contents successfully saved...
275 // Clean out archived versions of this page.
276 include_once('lib/ArchiveCleaner.php');
277 $cleaner = new ArchiveCleaner($GLOBALS['ExpireParams']);
278 $cleaner->cleanPageRevisions($page);
280 /* generate notification emails done in WikiDB::save to catch all direct calls
283 // look at the errorstack
284 $errors = $GLOBALS['ErrorManager']->_postponed_errors;
285 $warnings = $GLOBALS['ErrorManager']->getPostponedErrorsAsHTML();
286 $GLOBALS['ErrorManager']->_postponed_errors = $errors;
288 $dbi = $request->getDbh();
292 if (empty($warnings->_content) && ! $WikiTheme->getImageURL('signature')) {
293 // Do redirect to browse page if no signature has
294 // been defined. In this case, the user will most
295 // likely not see the rest of the HTML we generate
297 $this->_redirectToBrowsePage();
300 // Force browse of current page version.
301 $request->setArg('version', false);
302 //$request->setArg('action', false);
304 $template = Template('savepage', $this->tokens);
305 $template->replace('CONTENT', $newrevision->getTransformedContent());
306 if (!empty($warnings->_content))
307 $template->replace('WARNINGS', $warnings);
309 $pagelink = WikiLink($page);
311 GeneratePage($template, fmt("Saved: %s", $pagelink), $newrevision);
315 function captchaFailed () {
316 if ($this->request->getSessionVar('captcha_ok') == true)
319 if ( ! array_key_exists ( 'captcha_input', $this->meta )
320 or ($this->request->getSessionVar('captchaword')
321 and ($this->request->getSessionVar('captchaword') != $this->meta['captcha_input'])))
324 $this->request->setSessionVar('captcha_ok', true);
328 function isConcurrentUpdate () {
329 assert($this->current->getVersion() >= $this->_currentVersion);
330 return $this->current->getVersion() != $this->_currentVersion;
333 function canEdit () {
334 return !$this->page->get('locked') || $this->user->isAdmin();
337 function isInitialEdit () {
338 return $this->_initialEdit;
341 function isUnchanged () {
342 $current = &$this->current;
344 if ($this->meta['markup'] != $current->get('markup'))
347 return $this->_content == $current->getPackedContent();
351 * Handle AntiSpam here. How? http://wikiblacklist.blogspot.com/
352 * Need to check dynamically some blacklist wikipage settings
353 * (plugin WikiAccessRestrictions) and some static blacklist.
355 * More then 20 new external links
356 * content patterns by babycart (only php >= 4.3 for now)
363 $current = &$this->current;
364 $request = &$this->request;
366 $oldtext = $current->getPackedContent();
367 $newtext =& $this->_content;
369 // FIXME: in longer texts the NUM_SPAM_LINKS number should be increased.
370 // better use a certain text:link ratio.
372 // 1. Not more then 20 new external links
373 if ($this->numLinks($newtext) - $this->numLinks($oldtext) >= NUM_SPAM_LINKS) {
374 // TODO: mail the admin?
375 $this->tokens['PAGE_LOCKED_MESSAGE'] =
376 HTML($this->getSpamMessage(),
377 HTML::p(HTML::em(_("Too many external links."))));
380 // 2. external babycart (SpamAssassin) check
381 // This will probably prevent from discussing sex or viagra related topics. So beware.
382 if (ENABLE_SPAMASSASSIN) {
383 $user = $request->getUser();
384 include_once("lib/spam_babycart.php");
385 if ($babycart = check_babycart($newtext, $request->get("REMOTE_ADDR"),
388 if (is_array($babycart))
389 $this->tokens['PAGE_LOCKED_MESSAGE'] =
390 HTML($this->getSpamMessage(),
391 HTML::p(HTML::em(_("SpamAssassin reports: ",
392 join("\n", $babycart)))));
399 /** Number of external links in the wikitext
401 function numLinks(&$text) {
402 return substr_count($text, "http://");
405 /** Header of the Anti Spam message
407 function getSpamMessage () {
409 HTML(HTML::h2(_("Spam Prevention")),
410 HTML::p(_("This page edit seems to contain spam and was therefore not saved."),
412 _("Sorry for the inconvenience.")),
416 function getPreview () {
417 include_once('lib/PageType.php');
418 $this->_content = $this->getContent();
419 return new TransformedText($this->page, $this->_content, $this->meta);
422 function getConvertedPreview () {
423 include_once('lib/PageType.php');
424 $this->_content = $this->getContent();
425 $this->meta['markup'] = 2.0;
426 $this->_content = ConvertOldMarkup($this->_content);
427 return new TransformedText($this->page, $this->_content, $this->meta);
430 // possibly convert HTMLAREA content back to Wiki markup
431 function getContent () {
432 if (ENABLE_WYSIWYG) {
433 $xml_output = Edit_WYSIWYG_ConvertAfter($this->_content);
434 //$this->_content = join("", $xml_output->_content);
435 return $this->_content;
437 return $this->_content;
441 function getLockedMessage () {
443 HTML(HTML::h2(_("Page Locked")),
444 HTML::p(_("This page has been locked by the administrator so your changes can not be saved.")),
445 HTML::p(_("(Copy your changes to the clipboard. You can try editing a different page or save your text in a text editor.)")),
446 HTML::p(_("Sorry for the inconvenience.")));
449 function getConflictMessage ($unresolved = false) {
451 xgettext only knows about c/c++ line-continuation strings
452 it does not know about php's dot operator.
453 We want to translate this entire paragraph as one string, of course.
456 //$re_edit_link = Button('edit', _("Edit the new version"), $this->page);
459 $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.",
460 "<<<<<<< ". _("Your version"),
461 ">>>>>>> ". _("Other version")));
463 $message = HTML::p(_("Please check it through before saving."));
467 /*$steps = HTML::ol(HTML::li(_("Copy your changes to the clipboard or to another temporary place (e.g. text editor).")),
468 HTML::li(fmt("%s of the page. You should now see the most current version of the page. Your changes are no longer there.",
470 HTML::li(_("Make changes to the file again. Paste your additions from the clipboard (or text editor).")),
471 HTML::li(_("Save your updated changes.")));
474 HTML(HTML::h2(_("Conflicting Edits!")),
475 HTML::p(_("In the time since you started editing this page, another user has saved a new version of it.")),
476 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.")),
481 function getTextArea () {
482 $request = &$this->request;
484 $readonly = ! $this->canEdit(); // || $this->isConcurrentUpdate();
486 // WYSIWYG will need two pagetypes: raw wikitest and converted html
487 if (ENABLE_WYSIWYG) {
488 $this->_wikicontent = $this->_content;
489 $this->_content = $this->getPreview();
490 // $html = $this->getPreview();
491 // $this->_content = $html->asXML();
494 $textarea = HTML::textarea(array('class'=> 'wikiedit',
495 'name' => 'edit[content]',
496 'id' => 'edit:content',
497 'rows' => $request->getPref('editHeight'),
498 'cols' => $request->getPref('editWidth'),
499 'readonly' => (bool) $readonly),
501 /** <textarea wrap="virtual"> is not valid xhtml but Netscape 4 requires it
502 * to wrap long lines.
505 $textarea->setAttr('wrap', 'virtual');
507 return Edit_WYSIWYG_Textarea($textarea, $this->_wikicontent, $textarea->getAttr('name'));
512 function getFormElements () {
514 $request = &$this->request;
515 $page = &$this->page;
517 $h = array('action' => 'edit',
518 'pagename' => $page->getName(),
519 'version' => $this->version,
520 'edit[pagetype]' => $this->meta['pagetype'],
521 'edit[current_version]' => $this->_currentVersion);
523 $el['HIDDEN_INPUTS'] = HiddenInputs($h);
524 $el['EDIT_TEXTAREA'] = $this->getTextArea();
525 if ( ENABLE_CAPTCHA && ! $request->getSessionVar('captchaword')) {
526 $request->setSessionVar('captchaword', get_captcha_word());
528 if ( ENABLE_CAPTCHA && ! $request->getSessionVar('captcha_ok')) {
530 = HTML::input(array('type' => 'text',
531 'class' => 'wikitext',
532 'id' => 'edit:captcha_input',
533 'name' => 'edit[captcha_input]',
535 'maxlength' => 256));
536 $el['CAPTCHA_IMAGE'] = '<img src="?action=captcha" alt="captcha" />';
537 $el['CAPTCHA_LABEL'] = '<label for="edit:captcha_input">'._("Type word above:").' </label>';
540 = HTML::input(array('type' => 'text',
541 'class' => 'wikitext',
542 'id' => 'edit:summary',
543 'name' => 'edit[summary]',
546 'value' => $this->meta['summary']));
548 = HTML::input(array('type' => 'checkbox',
549 'name' => 'edit[minor_edit]',
550 'id' => 'edit:minor_edit',
551 'checked' => (bool) $this->meta['is_minor_edit']));
553 = HTML::input(array('type' => 'checkbox',
554 'name' => 'edit[markup]',
556 'checked' => $this->meta['markup'] < 2.0,
557 'id' => 'useOldMarkup',
558 'onclick' => 'showOldMarkupRules(this.checked)'));
559 $el['OLD_MARKUP_CONVERT'] = ($this->meta['markup'] < 2.0)
560 ? Button('submit:edit[edit_convert]', _("Convert"), 'wikiaction') : '';
562 = HTML::input(array('type' => 'checkbox',
563 'name' => 'edit[locked]',
564 'id' => 'edit:locked',
565 'disabled' => (bool) !$this->user->isadmin(),
566 'checked' => (bool) $this->locked));
568 $el['PREVIEW_B'] = Button('submit:edit[preview]', _("Preview"),
571 //if (!$this->isConcurrentUpdate() && $this->canEdit())
572 $el['SAVE_B'] = Button('submit:edit[save]', _("Save"), 'wikiaction');
574 $el['IS_CURRENT'] = $this->version == $this->current->getVersion();
577 = HTML::input(array('type' => 'text',
580 'class' => "numeric",
581 'name' => 'pref[editWidth]',
582 'id' => 'pref:editWidth',
583 'value' => $request->getPref('editWidth'),
584 'onchange' => 'this.form.submit();'));
586 = HTML::input(array('type' => 'text',
589 'class' => "numeric",
590 'name' => 'pref[editHeight]',
591 'id' => 'pref:editHeight',
592 'value' => $request->getPref('editHeight'),
593 'onchange' => 'this.form.submit();'));
594 $el['SEP'] = $WikiTheme->getButtonSeparator();
595 $el['AUTHOR_MESSAGE'] = fmt("Author will be logged as %s.", HTML::em($this->user->getId()));
600 function _redirectToBrowsePage() {
601 $this->request->redirect(WikiURL($this->page, false, 'absolute_url'));
604 function _restoreState () {
605 $request = &$this->request;
607 $posted = $request->getArg('edit');
608 $request->setArg('edit', false);
610 if (!$posted || !$request->isPost()
611 || $request->getArg('action') != 'edit')
614 if (!isset($posted['content']) || !is_string($posted['content']))
616 $this->_content = preg_replace('/[ \t\r]+\n/', "\n",
617 rtrim($posted['content']));
618 $this->_content = $this->getContent();
620 $this->_currentVersion = (int) $posted['current_version'];
622 if ($this->_currentVersion < 0)
624 if ($this->_currentVersion > $this->current->getVersion())
625 return false; // FIXME: some kind of warning?
627 $is_old_markup = !empty($posted['markup']) && $posted['markup'] == 'old';
628 $meta['markup'] = $is_old_markup ? false : 2.0;
629 $meta['summary'] = trim(substr($posted['summary'], 0, 256));
630 $meta['is_minor_edit'] = !empty($posted['minor_edit']);
631 $meta['pagetype'] = !empty($posted['pagetype']) ? $posted['pagetype'] : false;
632 if ( ENABLE_CAPTCHA )
633 $meta['captcha_input'] = !empty($posted['captcha_input']) ?
634 $posted['captcha_input'] : '';
636 $this->meta = array_merge($this->meta, $meta);
637 $this->locked = !empty($posted['locked']);
639 if (!empty($posted['preview']))
640 $this->editaction = 'preview';
641 elseif (!empty($posted['save']))
642 $this->editaction = 'save';
643 elseif (!empty($posted['edit_convert']))
644 $this->editaction = 'edit_convert';
646 $this->editaction = 'edit';
651 function _initializeState () {
652 $request = &$this->request;
653 $current = &$this->current;
654 $selected = &$this->selected;
655 $user = &$this->user;
658 NoSuchRevision($request, $this->page, $this->version); // noreturn
660 $this->_currentVersion = $current->getVersion();
661 $this->_content = $selected->getPackedContent();
663 $this->locked = $this->page->get('locked');
665 // If author same as previous author, default minor_edit to on.
666 $age = $this->meta['mtime'] - $current->get('mtime');
667 $this->meta['is_minor_edit'] = ( $age < MINOR_EDIT_TIMEOUT
668 && $current->get('author') == $user->getId()
671 // Default for new pages is new-style markup.
672 if ($selected->hasDefaultContents())
673 $is_new_markup = true;
675 $is_new_markup = $selected->get('markup') >= 2.0;
677 $this->meta['markup'] = $is_new_markup ? 2.0: false;
678 $this->meta['pagetype'] = $selected->get('pagetype');
679 if ($this->meta['pagetype'] == 'wikiblog')
680 $this->meta['summary'] = $selected->get('summary'); // keep blog title
682 $this->meta['summary'] = '';
683 $this->editaction = 'edit';
687 class LoadFileConflictPageEditor
690 function editPage ($saveFailed = true) {
691 $tokens = &$this->tokens;
693 if (!$this->canEdit()) {
694 if ($this->isInitialEdit())
695 return $this->viewSource();
696 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
698 elseif ($this->editaction == 'save') {
699 if ($this->savePage())
700 return true; // Page saved.
704 if ($saveFailed || $this->isConcurrentUpdate())
706 // Get the text of the original page, and the two conflicting edits
707 // The diff class takes arrays as input. So retrieve content as
708 // an array, or convert it as necesary.
709 $orig = $this->page->getRevision($this->_currentVersion);
710 $this_content = explode("\n", $this->_content);
711 $other_content = $this->current->getContent();
712 include_once("lib/diff.php");
713 $diff2 = new Diff($other_content, $this_content);
714 $context_lines = max(4, count($other_content) + 1,
715 count($this_content) + 1);
716 $fmt = new BlockDiffFormatter($context_lines);
718 $this->_content = $fmt->format($diff2);
719 // FIXME: integrate this into class BlockDiffFormatter
720 $this->_content = str_replace(">>>>>>>\n<<<<<<<\n", "=======\n",
722 $this->_content = str_replace("<<<<<<<\n>>>>>>>\n", "=======\n",
725 $this->_currentVersion = $this->current->getVersion();
726 $this->version = $this->_currentVersion;
727 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage();
730 if ($this->editaction == 'edit_convert')
731 $tokens['PREVIEW_CONTENT'] = $this->getConvertedPreview();
732 if ($this->editaction == 'preview')
733 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
735 // FIXME: NOT_CURRENT_MESSAGE?
736 $tokens = array_merge($tokens, $this->getFormElements());
738 return $this->output('editpage', _("Merge and Edit: %s"));
739 // FIXME: this doesn't display
742 function output ($template, $title_fs) {
743 $selected = &$this->selected;
744 $current = &$this->current;
746 if ($selected && $selected->getVersion() != $current->getVersion()) {
748 $pagelink = WikiLink($selected);
752 $pagelink = WikiLink($this->page);
755 $title = new FormattedText ($title_fs, $pagelink);
756 $template = Template($template, $this->tokens);
758 //GeneratePage($template, $title, $rev);
762 function getConflictMessage () {
763 $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.",
766 HTML::p(_("Please check it through before saving."))));
772 $Log: not supported by cvs2svn $
773 Revision 1.97 2005/09/26 06:32:22 rurban
774 [] is forbidden in id tags. Renamed to use :
776 Revision 1.96 2005/05/06 17:54:22 rurban
777 silence Preview warnings for PAGE_LOCKED_MESSAGE, CONCURRENT_UPDATE_MESSAGE (thanks to schorni)
779 Revision 1.95 2005/04/25 20:17:14 rurban
780 captcha feature by Benjamin Drieu. Patch #1110699
782 Revision 1.94 2005/02/28 20:23:31 rurban
785 Revision 1.93 2005/02/27 19:31:52 rurban
786 hack: display errorstack without sideeffects (save and restore)
788 Revision 1.92 2005/01/29 20:37:21 rurban
789 no edit toolbar at all if ENABLE_EDITTOOLBAR = false
791 Revision 1.91 2005/01/25 07:05:49 rurban
792 extract toolbar code, support new tags to get rid of php inside templates
794 Revision 1.90 2005/01/22 12:46:15 rurban
795 fix oldmakrup button label
796 update pref[edit*] settings
798 Revision 1.89 2005/01/21 14:07:49 rurban
801 Revision 1.88 2004/12/17 16:39:03 rurban
804 Revision 1.87 2004/12/16 18:28:05 rurban
805 keep wikiblog summary = page title
807 Revision 1.86 2004/12/11 14:50:15 rurban
808 new edit_convert button, to get rid of old markup eventually
810 Revision 1.85 2004/12/06 19:49:56 rurban
811 enable action=remove which is undoable and seeable in RecentChanges: ADODB ony for now.
812 renamed delete_page to purge_page.
813 enable action=edit&version=-1 to force creation of a new version.
814 added BABYCART_PATH config
815 fixed magiqc in adodb.inc.php
818 Revision 1.84 2004/12/04 12:58:26 rurban
819 enable babycart Blog::SpamAssassin module on ENABLE_SPAMASSASSIN=true
820 (currently only for php >= 4.3.0)
822 Revision 1.83 2004/12/04 11:55:39 rurban
823 First simple AntiSpam prevention:
824 No more than 20 new http:// links allowed
826 Revision 1.82 2004/11/30 22:21:56 rurban
827 changed gif to optimized (pngout) png
829 Revision 1.81 2004/11/29 17:57:27 rurban
830 translated pulldown buttons
832 Revision 1.80 2004/11/25 17:20:51 rurban
833 and again a couple of more native db args: backlinks
835 Revision 1.79 2004/11/21 11:59:20 rurban
836 remove final \n to be ob_cache independent
838 Revision 1.78 2004/11/16 17:57:45 rurban
839 fix search&replace button
840 use new addTagButton machinery
841 new showPulldown for categories, TODO: in a seperate request
843 Revision 1.77 2004/11/15 15:52:35 rurban
846 Revision 1.76 2004/11/15 15:37:34 rurban
848 don't use document.write for replace, otherwise self.opener is not defined.
850 Revision 1.75 2004/09/16 08:00:52 rurban
853 Revision 1.74 2004/07/03 07:36:28 rurban
854 do not get unneccessary content
856 Revision 1.73 2004/06/16 21:23:44 rurban
857 fixed non-object fatal #215
859 Revision 1.72 2004/06/14 11:31:37 rurban
860 renamed global $Theme to $WikiTheme (gforge nameclash)
861 inherit PageList default options from PageList
862 default sortby=pagename
863 use options in PageList_Selectable (limit, sortby, ...)
864 added action revert, with button at action=diff
865 added option regex to WikiAdminSearchReplace
867 Revision 1.71 2004/06/03 18:06:29 rurban
868 fix file locking issues (only needed on write)
869 fixed immediate LANG and THEME in-session updates if not stored in prefs
870 advanced editpage toolbars (search & replace broken)
872 Revision 1.70 2004/06/02 20:47:47 rurban
873 dont use the wikiaction class
875 Revision 1.69 2004/06/02 10:17:56 rurban
876 integrated search/replace into toolbar
877 added save+preview buttons
879 Revision 1.68 2004/06/01 15:28:00 rurban
880 AdminUser only ADMIN_USER not member of Administrators
881 some RateIt improvements by dfrankow
884 Revision _1.6 2004/05/26 15:48:00 syilek
885 fixed problem with creating page with slashes from one true page
887 Revision _1.5 2004/05/25 16:51:53 syilek
888 added ability to create a page from the category page and not have to edit it
890 Revision 1.67 2004/05/27 17:49:06 rurban
891 renamed DB_Session to DbSession (in CVS also)
892 added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
893 remove leading slash in error message
894 added force_unlock parameter to File_Passwd (no return on stale locks)
895 fixed adodb session AffectedRows
896 added FileFinder helpers to unify local filenames and DATA_PATH names
897 editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
899 Revision 1.66 2004/04/29 23:25:12 rurban
900 re-ordered locale init (as in 1.3.9)
901 fixed loadfile with subpages, and merge/restore anyway
904 Revision 1.65 2004/04/18 01:11:52 rurban
905 more numeric pagename fixes.
906 fixed action=upload with merge conflict warnings.
907 charset changed from constant to global (dynamic utf-8 switching)
909 Revision 1.64 2004/04/06 19:48:56 rurban
910 temp workaround for action=edit AddComment form
912 Revision 1.63 2004/03/24 19:39:02 rurban
913 php5 workaround code (plus some interim debugging code in XmlElement)
914 php5 doesn't work yet with the current XmlElement class constructors,
915 WikiUserNew does work better than php4.
916 rewrote WikiUserNew user upgrading to ease php5 update
917 fixed pref handling in WikiUserNew
918 added Email Notification
919 added simple Email verification
920 removed emailVerify userpref subclass: just a email property
921 changed pref binary storage layout: numarray => hash of non default values
922 print optimize message only if really done.
923 forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
924 prefs should be stored in db or homepage, besides the current session.
926 Revision 1.62 2004/03/17 18:41:05 rurban
927 initial_content and template support for CreatePage
929 Revision 1.61 2004/03/12 20:59:17 rurban
930 important cookie fix by Konstantin Zadorozhny
931 new editpage feature: JS_SEARCHREPLACE
933 Revision 1.60 2004/02/15 21:34:37 rurban
934 PageList enhanced and improved.
935 fixed new WikiAdmin... plugins
936 editpage, Theme with exp. htmlarea framework
937 (htmlarea yet committed, this is really questionable)
938 WikiUser... code with better session handling for prefs
939 enhanced UserPreferences (again)
940 RecentChanges for show_deleted: how should pages be deleted then?
942 Revision 1.59 2003/12/07 20:35:26 carstenklapp
943 Bugfix: Concurrent updates broken since after 1.3.4 release: Fatal
944 error: Call to undefined function: gettransformedcontent() in
945 /home/groups/p/ph/phpwiki/htdocs/phpwiki2/lib/editpage.php on line
948 Revision 1.58 2003/03/10 18:25:22 dairiki
949 Bug/typo fix. If you use the edit page to un/lock a page, it
950 failed with: Fatal error: Call to a member function on a
951 non-object in editpage.php on line 136
953 Revision 1.57 2003/02/26 03:40:22 dairiki
954 New action=create. Essentially the same as action=edit, except that if the
955 page already exists, it falls back to action=browse.
957 This is for use in the "question mark" links for unknown wiki words
958 to avoid problems and confusion when following links from stale pages.
959 (If the "unknown page" has been created in the interim, the user probably
960 wants to view the page before editing it.)
962 Revision 1.56 2003/02/21 18:07:14 dairiki
963 Minor, nitpicky, currently inconsequential changes.
965 Revision 1.55 2003/02/21 04:10:58 dairiki
966 Fixes for new cached markup.
967 Some minor code cleanups.
969 Revision 1.54 2003/02/16 19:47:16 dairiki
970 Update WikiDB timestamp when editing or deleting pages.
972 Revision 1.53 2003/02/15 23:20:27 dairiki
973 Redirect back to browse current version of page upon save,
974 even when no changes were made.
976 Revision 1.52 2003/01/03 22:22:00 carstenklapp
977 Minor adjustments to diff block markers ("<<<<<<<"). Source reformatting.
979 Revision 1.51 2003/01/03 02:43:26 carstenklapp
980 New class LoadFileConflictPageEditor, for merging / comparing a loaded
981 pgsrc file with an existing page.
989 // c-hanging-comment-ender-p: nil
990 // indent-tabs-mode: nil