2 rcs_id('$Id: editpage.php,v 1.100 2005-10-30 14:20:42 rurban Exp $');
4 require_once('lib/Template.php');
8 function PageEditor (&$request) {
9 $this->request = &$request;
11 $this->user = $request->getUser();
12 $this->page = $request->getPage();
14 $this->current = $this->page->getCurrentRevision(false);
16 // HACKish short circuit to browse on action=create
17 if ($request->getArg('action') == 'create') {
18 if (! $this->current->hasDefaultContents())
19 $request->redirect(WikiURL($this->page->getName())); // noreturn
23 $this->meta = array('author' => $this->user->getId(),
24 'author_id' => $this->user->getAuthenticatedId(),
27 $this->tokens = array();
30 require_once("lib/WysiwygEdit.php");
31 if (USE_TINYMCE) $backend = "tinymce";
32 elseif (USE_HTMLAREA3) $backend = "htmlarea3";
33 elseif (USE_HTMLAREA2) $backend = "htmlarea2";
34 else trigger_error("undefined WysiwygEdit backend", E_USER_ERROR);
36 require_once("lib/WysiwygEdit/$backend.php");
37 $class = "WysiwygEdit_$backend";
38 $this->WysiwygEdit = new $class();
41 require_once('lib/Captcha.php');
42 $this->Captcha = new Captcha($this->meta);
45 $version = $request->getArg('version');
46 if ($version !== false) {
47 $this->selected = $this->page->getRevision($version);
48 $this->version = $version;
51 $this->version = $this->current->getVersion();
52 $this->selected = $this->page->getRevision($this->version);
55 if ($this->_restoreState()) {
56 $this->_initialEdit = false;
59 $this->_initializeState();
60 $this->_initialEdit = true;
62 // The edit request has specified some initial content from a template
63 if ( ($template = $request->getArg('template'))
64 and $request->_dbi->isWikiPage($template)) {
65 $page = $request->_dbi->getPage($template);
66 $current = $page->getCurrentRevision();
67 $this->_content = $current->getPackedContent();
68 } elseif ($initial_content = $request->getArg('initial_content')) {
69 $this->_content = $initial_content;
70 $this->_redirect_to = $request->getArg('save_and_redirect_to');
74 header("Content-Type: text/html; charset=" . $GLOBALS['charset']);
77 function editPage () {
80 $tokens = &$this->tokens;
81 $tokens['PAGE_LOCKED_MESSAGE'] = '';
82 $tokens['CONCURRENT_UPDATE_MESSAGE'] = '';
84 if (isset($this->request->args['pref']['editWidth'])
85 and ($this->request->getPref('editWidth') != $this->request->args['pref']['editWidth'])) {
86 $this->request->_prefs->set('editWidth', $this->request->args['pref']['editWidth']);
88 if (isset($this->request->args['pref']['editHeight'])
89 and ($this->request->getPref('editHeight') != $this->request->args['pref']['editHeight'])) {
90 $this->request->_prefs->set('editHeight', $this->request->args['pref']['editHeight']);
93 if (! $this->canEdit()) {
94 if ($this->isInitialEdit())
95 return $this->viewSource();
96 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
98 elseif ($this->request->getArg('save_and_redirect_to') != "") {
99 if (ENABLE_CAPTCHA && $this->Captcha->Failed()) {
100 $this->tokens['PAGE_LOCKED_MESSAGE'] =
101 HTML::p(HTML::h1($this->Captcha->failed_msg));
103 elseif ( $this->savePage()) {
105 $this->request->redirect(WikiURL($this->request->getArg('save_and_redirect_to')));
106 return true; // Page saved.
110 elseif ($this->editaction == 'save') {
111 if (ENABLE_CAPTCHA && $this->Captcha->Failed()) {
112 $this->tokens['PAGE_LOCKED_MESSAGE'] =
113 HTML::p(HTML::h1($this->Captcha->failed_msg));
115 elseif ($this->savePage()) {
116 return true; // Page saved.
123 if ($saveFailed and $this->isConcurrentUpdate())
125 // Get the text of the original page, and the two conflicting edits
126 // The diff3 class takes arrays as input. So retrieve content as
127 // an array, or convert it as necesary.
128 $orig = $this->page->getRevision($this->_currentVersion);
129 // FIXME: what if _currentVersion has be deleted?
130 $orig_content = $orig->getContent();
131 $this_content = explode("\n", $this->_content);
132 $other_content = $this->current->getContent();
133 include_once("lib/diff3.php");
134 $diff = new diff3($orig_content, $this_content, $other_content);
135 $output = $diff->merged_output(_("Your version"), _("Other version"));
136 // Set the content of the textarea to the merged diff
137 // output, and update the version
138 $this->_content = implode ("\n", $output);
139 $this->_currentVersion = $this->current->getVersion();
140 $this->version = $this->_currentVersion;
141 $unresolved = $diff->ConflictingBlocks;
142 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage($unresolved);
143 } elseif ($saveFailed && !$this->_isSpam) {
144 $tokens['CONCURRENT_UPDATE_MESSAGE'] =
145 HTML(HTML::h2(_("Some internal editing error")),
146 HTML::p(_("Your are probably trying to edit/create an invalid version of this page.")),
147 HTML::p(HTML::em(_("&version=-1 might help."))));
150 if ($this->editaction == 'edit_convert')
151 $tokens['PREVIEW_CONTENT'] = $this->getConvertedPreview();
152 if ($this->editaction == 'preview')
153 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
155 // FIXME: NOT_CURRENT_MESSAGE?
156 $tokens = array_merge($tokens, $this->getFormElements());
158 if (ENABLE_EDIT_TOOLBAR and !ENABLE_WYSIWYG) {
159 include_once("lib/EditToolbar.php");
160 $toolbar = new EditToolbar();
161 $tokens = array_merge($tokens, $toolbar->getTokens());
164 return $this->output('editpage', _("Edit: %s"));
167 function output ($template, $title_fs) {
169 $selected = &$this->selected;
170 $current = &$this->current;
172 if ($selected && $selected->getVersion() != $current->getVersion()) {
174 $pagelink = WikiLink($selected);
178 $pagelink = WikiLink($this->page);
181 $title = new FormattedText ($title_fs, $pagelink);
182 // not for dumphtml or viewsource
183 if (ENABLE_WYSIWYG and $template == 'editpage') {
184 $WikiTheme->addMoreHeaders($this->WysiwygEdit->Head());
185 //$tokens['PAGE_SOURCE'] = $WysiwygEdit->ConvertBefore($this->_content);
187 $template = Template($template, $this->tokens);
188 GeneratePage($template, $title, $rev);
193 function viewSource () {
194 assert($this->isInitialEdit());
195 assert($this->selected);
197 $this->tokens['PAGE_SOURCE'] = $this->_content;
198 return $this->output('viewsource', _("View Source: %s"));
201 function updateLock() {
202 if ((bool)$this->page->get('locked') == (bool)$this->locked)
203 return false; // Not changed.
205 if (!$this->user->isAdmin()) {
206 // FIXME: some sort of message
207 return false; // not allowed.
210 $this->page->set('locked', (bool)$this->locked);
211 $this->tokens['LOCK_CHANGED_MSG']
212 = $this->locked ? _("Page now locked.") : _("Page now unlocked.");
214 return true; // lock changed.
217 function savePage () {
218 $request = &$this->request;
220 if ($this->isUnchanged()) {
221 // Allow admin lock/unlock even if
222 // no text changes were made.
223 if ($this->updateLock()) {
224 $dbi = $request->getDbh();
227 // Save failed. No changes made.
228 $this->_redirectToBrowsePage();
229 // user will probably not see the rest of this...
230 include_once('lib/display.php');
231 // force browse of current version:
232 $request->setArg('version', false);
233 displayPage($request, 'nochanges');
237 if ($this->isSpam()) {
238 $this->_isSpam = true;
241 // Save failed. No changes made.
242 $this->_redirectToBrowsePage();
243 // user will probably not see the rest of this...
244 include_once('lib/display.php');
245 // force browse of current version:
246 $request->setArg('version', false);
247 displayPage($request, 'nochanges');
252 $page = &$this->page;
254 // Include any meta-data from original page version which
255 // has not been explicitly updated.
256 // (Except don't propagate pgsrc_version --- moot for now,
257 // because at present it never gets into the db...)
258 $meta = $this->selected->getMetaData();
259 unset($meta['pgsrc_version']);
260 $meta = array_merge($meta, $this->meta);
263 $this->_content = $this->getContent();
264 $newrevision = $page->save($this->_content,
267 : $this->_currentVersion + 1,
270 if (!isa($newrevision, 'WikiDB_PageRevision')) {
271 // Save failed. (Concurrent updates).
275 // New contents successfully saved...
278 // Clean out archived versions of this page.
279 include_once('lib/ArchiveCleaner.php');
280 $cleaner = new ArchiveCleaner($GLOBALS['ExpireParams']);
281 $cleaner->cleanPageRevisions($page);
283 /* generate notification emails done in WikiDB::save to catch all direct calls
286 // look at the errorstack
287 $errors = $GLOBALS['ErrorManager']->_postponed_errors;
288 $warnings = $GLOBALS['ErrorManager']->getPostponedErrorsAsHTML();
289 $GLOBALS['ErrorManager']->_postponed_errors = $errors;
291 $dbi = $request->getDbh();
295 if (empty($warnings->_content) && ! $WikiTheme->getImageURL('signature')) {
296 // Do redirect to browse page if no signature has
297 // been defined. In this case, the user will most
298 // likely not see the rest of the HTML we generate
300 $this->_redirectToBrowsePage();
303 // Force browse of current page version.
304 $request->setArg('version', false);
305 //$request->setArg('action', false);
307 $template = Template('savepage', $this->tokens);
308 $template->replace('CONTENT', $newrevision->getTransformedContent());
309 if (!empty($warnings->_content))
310 $template->replace('WARNINGS', $warnings);
312 $pagelink = WikiLink($page);
314 GeneratePage($template, fmt("Saved: %s", $pagelink), $newrevision);
318 function isConcurrentUpdate () {
319 assert($this->current->getVersion() >= $this->_currentVersion);
320 return $this->current->getVersion() != $this->_currentVersion;
323 function canEdit () {
324 return !$this->page->get('locked') || $this->user->isAdmin();
327 function isInitialEdit () {
328 return $this->_initialEdit;
331 function isUnchanged () {
332 $current = &$this->current;
334 if ($this->meta['markup'] != $current->get('markup'))
337 return $this->_content == $current->getPackedContent();
341 * Handle AntiSpam here. How? http://wikiblacklist.blogspot.com/
342 * Need to check dynamically some blacklist wikipage settings
343 * (plugin WikiAccessRestrictions) and some static blacklist.
345 * Always: More then 20 new external links
346 * ENABLE_SPAMASSASSIN: content patterns by babycart (only php >= 4.3 for now)
347 * ENABLE_SPAMBLOCKLIST: IP blacklist, domain blacklist, url patterns
350 $current = &$this->current;
351 $request = &$this->request;
353 $oldtext = $current->getPackedContent();
354 $newtext =& $this->_content;
356 // FIXME: in longer texts the NUM_SPAM_LINKS number should be increased.
357 // better use a certain text : link ratio.
359 // 1. Not more then 20 new external links
360 if ($this->numLinks($newtext) - $this->numLinks($oldtext) >= NUM_SPAM_LINKS) {
361 // TODO: mail the admin?
362 $this->tokens['PAGE_LOCKED_MESSAGE'] =
363 HTML($this->getSpamMessage(),
364 HTML::p(HTML::strong(_("Too many external links."))));
367 // 2. external babycart (SpamAssassin) check
368 // This will probably prevent from discussing sex or viagra related topics. So beware.
369 if (ENABLE_SPAMASSASSIN) {
370 $user = $request->getUser();
371 include_once("lib/spam_babycart.php");
372 if ($babycart = check_babycart($newtext, $request->get("REMOTE_ADDR"),
374 // TODO: mail the admin
375 if (is_array($babycart))
376 $this->tokens['PAGE_LOCKED_MESSAGE'] =
377 HTML($this->getSpamMessage(),
378 HTML::p(HTML::em(_("SpamAssassin reports: ",
379 join("\n", $babycart)))));
383 // 3. extract (new) links and check surbl for blocked domains
384 if (ENABLE_SPAMBLOCKLIST and $this->numLinks($newtext)) {
385 include_once("lib/SpamBlocklist.php");
386 include_once("lib/InlineParser.php");
387 $parsed = TransformLinks($newtext);
388 foreach ($parsed->_content as $link) {
389 if (isa($link, 'Cached_ExternalLink')) {
390 $uri = $link->_getURL($this->page->getName());
391 if ($res = IsBlackListed($uri)) {
392 // TODO: mail the admin
393 $this->tokens['PAGE_LOCKED_MESSAGE'] =
394 HTML($this->getSpamMessage(),
395 HTML::p(HTML::strong(_("External links contain blocked domains:")),
396 HTML::ul(HTML::li(sprintf(_("%s is listed at %s"),
397 $res[2], $res[0])))));
407 /** Number of external links in the wikitext
409 function numLinks(&$text) {
410 return substr_count($text, "http://") + substr_count($text, "https://");
413 /** Header of the Anti Spam message
415 function getSpamMessage () {
417 HTML(HTML::h2(_("Spam Prevention")),
418 HTML::p(_("This page edit seems to contain spam and was therefore not saved."),
420 _("Sorry for the inconvenience.")),
424 function getPreview () {
425 include_once('lib/PageType.php');
426 $this->_content = $this->getContent();
427 return new TransformedText($this->page, $this->_content, $this->meta);
430 function getConvertedPreview () {
431 include_once('lib/PageType.php');
432 $this->_content = $this->getContent();
433 $this->meta['markup'] = 2.0;
434 $this->_content = ConvertOldMarkup($this->_content);
435 return new TransformedText($this->page, $this->_content, $this->meta);
438 // possibly convert HTMLAREA content back to Wiki markup
439 function getContent () {
440 if (ENABLE_WYSIWYG) {
441 $xml_output = $this->WysiwygEdit->ConvertAfter($this->_content);
442 //$this->_content = join("", $xml_output->_content);
443 return $this->_content;
445 return $this->_content;
449 function getLockedMessage () {
451 HTML(HTML::h2(_("Page Locked")),
452 HTML::p(_("This page has been locked by the administrator so your changes can not be saved.")),
453 HTML::p(_("(Copy your changes to the clipboard. You can try editing a different page or save your text in a text editor.)")),
454 HTML::p(_("Sorry for the inconvenience.")));
457 function getConflictMessage ($unresolved = false) {
459 xgettext only knows about c/c++ line-continuation strings
460 it does not know about php's dot operator.
461 We want to translate this entire paragraph as one string, of course.
464 //$re_edit_link = Button('edit', _("Edit the new version"), $this->page);
467 $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.",
468 "<<<<<<< ". _("Your version"),
469 ">>>>>>> ". _("Other version")));
471 $message = HTML::p(_("Please check it through before saving."));
475 /*$steps = HTML::ol(HTML::li(_("Copy your changes to the clipboard or to another temporary place (e.g. text editor).")),
476 HTML::li(fmt("%s of the page. You should now see the most current version of the page. Your changes are no longer there.",
478 HTML::li(_("Make changes to the file again. Paste your additions from the clipboard (or text editor).")),
479 HTML::li(_("Save your updated changes.")));
482 HTML(HTML::h2(_("Conflicting Edits!")),
483 HTML::p(_("In the time since you started editing this page, another user has saved a new version of it.")),
484 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.")),
489 function getTextArea () {
490 $request = &$this->request;
492 $readonly = ! $this->canEdit(); // || $this->isConcurrentUpdate();
494 // WYSIWYG will need two pagetypes: raw wikitest and converted html
495 if (ENABLE_WYSIWYG) {
496 $this->_wikicontent = $this->_content;
497 $this->_content = $this->getPreview();
498 // $html = $this->getPreview();
499 // $this->_content = $html->asXML();
502 $textarea = HTML::textarea(array('class'=> 'wikiedit',
503 'name' => 'edit[content]',
504 'id' => 'edit:content',
505 'rows' => $request->getPref('editHeight'),
506 'cols' => $request->getPref('editWidth'),
507 'readonly' => (bool) $readonly),
509 /** <textarea wrap="virtual"> is not valid xhtml but Netscape 4 requires it
510 * to wrap long lines.
513 $textarea->setAttr('wrap', 'virtual');
514 if (ENABLE_WYSIWYG) {
515 return $this->WysiwygEdit->Textarea($textarea, $this->_wikicontent,
516 $textarea->getAttr('name'));
521 function getFormElements () {
523 $request = &$this->request;
524 $page = &$this->page;
526 $h = array('action' => 'edit',
527 'pagename' => $page->getName(),
528 'version' => $this->version,
529 'edit[pagetype]' => $this->meta['pagetype'],
530 'edit[current_version]' => $this->_currentVersion);
532 $el['HIDDEN_INPUTS'] = HiddenInputs($h);
533 $el['EDIT_TEXTAREA'] = $this->getTextArea();
534 if ( ENABLE_CAPTCHA ) {
535 $el = array_merge($el, $this->Captcha->getFormElements());
538 = HTML::input(array('type' => 'text',
539 'class' => 'wikitext',
540 'id' => 'edit:summary',
541 'name' => 'edit[summary]',
544 'value' => $this->meta['summary']));
546 = HTML::input(array('type' => 'checkbox',
547 'name' => 'edit[minor_edit]',
548 'id' => 'edit:minor_edit',
549 'checked' => (bool) $this->meta['is_minor_edit']));
551 = HTML::input(array('type' => 'checkbox',
552 'name' => 'edit[markup]',
554 'checked' => $this->meta['markup'] < 2.0,
555 'id' => 'useOldMarkup',
556 'onclick' => 'showOldMarkupRules(this.checked)'));
557 $el['OLD_MARKUP_CONVERT'] = ($this->meta['markup'] < 2.0)
558 ? Button('submit:edit[edit_convert]', _("Convert"), 'wikiaction') : '';
560 = HTML::input(array('type' => 'checkbox',
561 'name' => 'edit[locked]',
562 'id' => 'edit:locked',
563 'disabled' => (bool) !$this->user->isadmin(),
564 'checked' => (bool) $this->locked));
566 $el['PREVIEW_B'] = Button('submit:edit[preview]', _("Preview"),
569 //if (!$this->isConcurrentUpdate() && $this->canEdit())
570 $el['SAVE_B'] = Button('submit:edit[save]', _("Save"), 'wikiaction');
572 $el['IS_CURRENT'] = $this->version == $this->current->getVersion();
575 = HTML::input(array('type' => 'text',
578 'class' => "numeric",
579 'name' => 'pref[editWidth]',
580 'id' => 'pref:editWidth',
581 'value' => $request->getPref('editWidth'),
582 'onchange' => 'this.form.submit();'));
584 = HTML::input(array('type' => 'text',
587 'class' => "numeric",
588 'name' => 'pref[editHeight]',
589 'id' => 'pref:editHeight',
590 'value' => $request->getPref('editHeight'),
591 'onchange' => 'this.form.submit();'));
592 $el['SEP'] = $WikiTheme->getButtonSeparator();
593 $el['AUTHOR_MESSAGE'] = fmt("Author will be logged as %s.",
594 HTML::em($this->user->getId()));
599 function _redirectToBrowsePage() {
600 $this->request->redirect(WikiURL($this->page, false, 'absolute_url'));
603 function _restoreState () {
604 $request = &$this->request;
606 $posted = $request->getArg('edit');
607 $request->setArg('edit', false);
609 if (!$posted || !$request->isPost()
610 || $request->getArg('action') != 'edit')
613 if (!isset($posted['content']) || !is_string($posted['content']))
615 $this->_content = preg_replace('/[ \t\r]+\n/', "\n",
616 rtrim($posted['content']));
617 $this->_content = $this->getContent();
619 $this->_currentVersion = (int) $posted['current_version'];
621 if ($this->_currentVersion < 0)
623 if ($this->_currentVersion > $this->current->getVersion())
624 return false; // FIXME: some kind of warning?
626 $is_old_markup = !empty($posted['markup']) && $posted['markup'] == 'old';
627 $meta['markup'] = $is_old_markup ? false : 2.0;
628 $meta['summary'] = trim(substr($posted['summary'], 0, 256));
629 $meta['is_minor_edit'] = !empty($posted['minor_edit']);
630 $meta['pagetype'] = !empty($posted['pagetype']) ? $posted['pagetype'] : false;
631 if ( ENABLE_CAPTCHA )
632 $meta['captcha_input'] = !empty($posted['captcha_input']) ?
633 $posted['captcha_input'] : '';
635 $this->meta = array_merge($this->meta, $meta);
636 $this->locked = !empty($posted['locked']);
638 if (!empty($posted['preview']))
639 $this->editaction = 'preview';
640 elseif (!empty($posted['save']))
641 $this->editaction = 'save';
642 elseif (!empty($posted['edit_convert']))
643 $this->editaction = 'edit_convert';
645 $this->editaction = 'edit';
650 function _initializeState () {
651 $request = &$this->request;
652 $current = &$this->current;
653 $selected = &$this->selected;
654 $user = &$this->user;
657 NoSuchRevision($request, $this->page, $this->version); // noreturn
659 $this->_currentVersion = $current->getVersion();
660 $this->_content = $selected->getPackedContent();
662 $this->locked = $this->page->get('locked');
664 // If author same as previous author, default minor_edit to on.
665 $age = $this->meta['mtime'] - $current->get('mtime');
666 $this->meta['is_minor_edit'] = ( $age < MINOR_EDIT_TIMEOUT
667 && $current->get('author') == $user->getId()
670 // Default for new pages is new-style markup.
671 if ($selected->hasDefaultContents())
672 $is_new_markup = true;
674 $is_new_markup = $selected->get('markup') >= 2.0;
676 $this->meta['markup'] = $is_new_markup ? 2.0: false;
677 $this->meta['pagetype'] = $selected->get('pagetype');
678 if ($this->meta['pagetype'] == 'wikiblog')
679 $this->meta['summary'] = $selected->get('summary'); // keep blog title
681 $this->meta['summary'] = '';
682 $this->editaction = 'edit';
686 class LoadFileConflictPageEditor
689 function editPage ($saveFailed = true) {
690 $tokens = &$this->tokens;
692 if (!$this->canEdit()) {
693 if ($this->isInitialEdit())
694 return $this->viewSource();
695 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
697 elseif ($this->editaction == 'save') {
698 if ($this->savePage())
699 return true; // Page saved.
703 if ($saveFailed || $this->isConcurrentUpdate())
705 // Get the text of the original page, and the two conflicting edits
706 // The diff class takes arrays as input. So retrieve content as
707 // an array, or convert it as necesary.
708 $orig = $this->page->getRevision($this->_currentVersion);
709 $this_content = explode("\n", $this->_content);
710 $other_content = $this->current->getContent();
711 include_once("lib/diff.php");
712 $diff2 = new Diff($other_content, $this_content);
713 $context_lines = max(4, count($other_content) + 1,
714 count($this_content) + 1);
715 $fmt = new BlockDiffFormatter($context_lines);
717 $this->_content = $fmt->format($diff2);
718 // FIXME: integrate this into class BlockDiffFormatter
719 $this->_content = str_replace(">>>>>>>\n<<<<<<<\n", "=======\n",
721 $this->_content = str_replace("<<<<<<<\n>>>>>>>\n", "=======\n",
724 $this->_currentVersion = $this->current->getVersion();
725 $this->version = $this->_currentVersion;
726 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage();
729 if ($this->editaction == 'edit_convert')
730 $tokens['PREVIEW_CONTENT'] = $this->getConvertedPreview();
731 if ($this->editaction == 'preview')
732 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
734 // FIXME: NOT_CURRENT_MESSAGE?
735 $tokens = array_merge($tokens, $this->getFormElements());
737 return $this->output('editpage', _("Merge and Edit: %s"));
738 // FIXME: this doesn't display
741 function output ($template, $title_fs) {
742 $selected = &$this->selected;
743 $current = &$this->current;
745 if ($selected && $selected->getVersion() != $current->getVersion()) {
747 $pagelink = WikiLink($selected);
751 $pagelink = WikiLink($this->page);
754 $title = new FormattedText ($title_fs, $pagelink);
755 $template = Template($template, $this->tokens);
757 //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.99 2005/10/29 08:21:58 rurban
774 ENABLE_SPAMBLOCKLIST:
775 Check for links to blocked external tld domains in new edits, against
776 multi.surbl.org and bl.spamcop.net.
778 Revision 1.98 2005/10/10 19:37:04 rurban
779 change USE_HTMLAREA to ENABLE WYSIWYG, add NUM_SPAM_LINKS=20
781 Revision 1.97 2005/09/26 06:32:22 rurban
782 [] is forbidden in id tags. Renamed to use :
784 Revision 1.96 2005/05/06 17:54:22 rurban
785 silence Preview warnings for PAGE_LOCKED_MESSAGE, CONCURRENT_UPDATE_MESSAGE (thanks to schorni)
787 Revision 1.95 2005/04/25 20:17:14 rurban
788 captcha feature by Benjamin Drieu. Patch #1110699
790 Revision 1.94 2005/02/28 20:23:31 rurban
793 Revision 1.93 2005/02/27 19:31:52 rurban
794 hack: display errorstack without sideeffects (save and restore)
796 Revision 1.92 2005/01/29 20:37:21 rurban
797 no edit toolbar at all if ENABLE_EDITTOOLBAR = false
799 Revision 1.91 2005/01/25 07:05:49 rurban
800 extract toolbar code, support new tags to get rid of php inside templates
802 Revision 1.90 2005/01/22 12:46:15 rurban
803 fix oldmakrup button label
804 update pref[edit*] settings
806 Revision 1.89 2005/01/21 14:07:49 rurban
809 Revision 1.88 2004/12/17 16:39:03 rurban
812 Revision 1.87 2004/12/16 18:28:05 rurban
813 keep wikiblog summary = page title
815 Revision 1.86 2004/12/11 14:50:15 rurban
816 new edit_convert button, to get rid of old markup eventually
818 Revision 1.85 2004/12/06 19:49:56 rurban
819 enable action=remove which is undoable and seeable in RecentChanges: ADODB ony for now.
820 renamed delete_page to purge_page.
821 enable action=edit&version=-1 to force creation of a new version.
822 added BABYCART_PATH config
823 fixed magiqc in adodb.inc.php
826 Revision 1.84 2004/12/04 12:58:26 rurban
827 enable babycart Blog::SpamAssassin module on ENABLE_SPAMASSASSIN=true
828 (currently only for php >= 4.3.0)
830 Revision 1.83 2004/12/04 11:55:39 rurban
831 First simple AntiSpam prevention:
832 No more than 20 new http:// links allowed
834 Revision 1.82 2004/11/30 22:21:56 rurban
835 changed gif to optimized (pngout) png
837 Revision 1.81 2004/11/29 17:57:27 rurban
838 translated pulldown buttons
840 Revision 1.80 2004/11/25 17:20:51 rurban
841 and again a couple of more native db args: backlinks
843 Revision 1.79 2004/11/21 11:59:20 rurban
844 remove final \n to be ob_cache independent
846 Revision 1.78 2004/11/16 17:57:45 rurban
847 fix search&replace button
848 use new addTagButton machinery
849 new showPulldown for categories, TODO: in a seperate request
851 Revision 1.77 2004/11/15 15:52:35 rurban
854 Revision 1.76 2004/11/15 15:37:34 rurban
856 don't use document.write for replace, otherwise self.opener is not defined.
858 Revision 1.75 2004/09/16 08:00:52 rurban
861 Revision 1.74 2004/07/03 07:36:28 rurban
862 do not get unneccessary content
864 Revision 1.73 2004/06/16 21:23:44 rurban
865 fixed non-object fatal #215
867 Revision 1.72 2004/06/14 11:31:37 rurban
868 renamed global $Theme to $WikiTheme (gforge nameclash)
869 inherit PageList default options from PageList
870 default sortby=pagename
871 use options in PageList_Selectable (limit, sortby, ...)
872 added action revert, with button at action=diff
873 added option regex to WikiAdminSearchReplace
875 Revision 1.71 2004/06/03 18:06:29 rurban
876 fix file locking issues (only needed on write)
877 fixed immediate LANG and THEME in-session updates if not stored in prefs
878 advanced editpage toolbars (search & replace broken)
880 Revision 1.70 2004/06/02 20:47:47 rurban
881 dont use the wikiaction class
883 Revision 1.69 2004/06/02 10:17:56 rurban
884 integrated search/replace into toolbar
885 added save+preview buttons
887 Revision 1.68 2004/06/01 15:28:00 rurban
888 AdminUser only ADMIN_USER not member of Administrators
889 some RateIt improvements by dfrankow
892 Revision _1.6 2004/05/26 15:48:00 syilek
893 fixed problem with creating page with slashes from one true page
895 Revision _1.5 2004/05/25 16:51:53 syilek
896 added ability to create a page from the category page and not have to edit it
898 Revision 1.67 2004/05/27 17:49:06 rurban
899 renamed DB_Session to DbSession (in CVS also)
900 added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
901 remove leading slash in error message
902 added force_unlock parameter to File_Passwd (no return on stale locks)
903 fixed adodb session AffectedRows
904 added FileFinder helpers to unify local filenames and DATA_PATH names
905 editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
907 Revision 1.66 2004/04/29 23:25:12 rurban
908 re-ordered locale init (as in 1.3.9)
909 fixed loadfile with subpages, and merge/restore anyway
912 Revision 1.65 2004/04/18 01:11:52 rurban
913 more numeric pagename fixes.
914 fixed action=upload with merge conflict warnings.
915 charset changed from constant to global (dynamic utf-8 switching)
917 Revision 1.64 2004/04/06 19:48:56 rurban
918 temp workaround for action=edit AddComment form
920 Revision 1.63 2004/03/24 19:39:02 rurban
921 php5 workaround code (plus some interim debugging code in XmlElement)
922 php5 doesn't work yet with the current XmlElement class constructors,
923 WikiUserNew does work better than php4.
924 rewrote WikiUserNew user upgrading to ease php5 update
925 fixed pref handling in WikiUserNew
926 added Email Notification
927 added simple Email verification
928 removed emailVerify userpref subclass: just a email property
929 changed pref binary storage layout: numarray => hash of non default values
930 print optimize message only if really done.
931 forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
932 prefs should be stored in db or homepage, besides the current session.
934 Revision 1.62 2004/03/17 18:41:05 rurban
935 initial_content and template support for CreatePage
937 Revision 1.61 2004/03/12 20:59:17 rurban
938 important cookie fix by Konstantin Zadorozhny
939 new editpage feature: JS_SEARCHREPLACE
941 Revision 1.60 2004/02/15 21:34:37 rurban
942 PageList enhanced and improved.
943 fixed new WikiAdmin... plugins
944 editpage, Theme with exp. htmlarea framework
945 (htmlarea yet committed, this is really questionable)
946 WikiUser... code with better session handling for prefs
947 enhanced UserPreferences (again)
948 RecentChanges for show_deleted: how should pages be deleted then?
950 Revision 1.59 2003/12/07 20:35:26 carstenklapp
951 Bugfix: Concurrent updates broken since after 1.3.4 release: Fatal
952 error: Call to undefined function: gettransformedcontent() in
953 /home/groups/p/ph/phpwiki/htdocs/phpwiki2/lib/editpage.php on line
956 Revision 1.58 2003/03/10 18:25:22 dairiki
957 Bug/typo fix. If you use the edit page to un/lock a page, it
958 failed with: Fatal error: Call to a member function on a
959 non-object in editpage.php on line 136
961 Revision 1.57 2003/02/26 03:40:22 dairiki
962 New action=create. Essentially the same as action=edit, except that if the
963 page already exists, it falls back to action=browse.
965 This is for use in the "question mark" links for unknown wiki words
966 to avoid problems and confusion when following links from stale pages.
967 (If the "unknown page" has been created in the interim, the user probably
968 wants to view the page before editing it.)
970 Revision 1.56 2003/02/21 18:07:14 dairiki
971 Minor, nitpicky, currently inconsequential changes.
973 Revision 1.55 2003/02/21 04:10:58 dairiki
974 Fixes for new cached markup.
975 Some minor code cleanups.
977 Revision 1.54 2003/02/16 19:47:16 dairiki
978 Update WikiDB timestamp when editing or deleting pages.
980 Revision 1.53 2003/02/15 23:20:27 dairiki
981 Redirect back to browse current version of page upon save,
982 even when no changes were made.
984 Revision 1.52 2003/01/03 22:22:00 carstenklapp
985 Minor adjustments to diff block markers ("<<<<<<<"). Source reformatting.
987 Revision 1.51 2003/01/03 02:43:26 carstenklapp
988 New class LoadFileConflictPageEditor, for merging / comparing a loaded
989 pgsrc file with an existing page.
997 // c-hanging-comment-ender-p: nil
998 // indent-tabs-mode: nil