2 rcs_id('$Id: editpage.php,v 1.102 2005-10-31 16:47:14 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 $backend = WYSIWYG_BACKEND;
31 require_once("lib/WysiwygEdit/$backend.php");
32 $class = "WysiwygEdit_$backend";
33 $this->WysiwygEdit = new $class();
36 require_once('lib/Captcha.php');
37 $this->Captcha = new Captcha($this->meta);
40 $version = $request->getArg('version');
41 if ($version !== false) {
42 $this->selected = $this->page->getRevision($version);
43 $this->version = $version;
46 $this->version = $this->current->getVersion();
47 $this->selected = $this->page->getRevision($this->version);
50 if ($this->_restoreState()) {
51 $this->_initialEdit = false;
54 $this->_initializeState();
55 $this->_initialEdit = true;
57 // The edit request has specified some initial content from a template
58 if ( ($template = $request->getArg('template'))
59 and $request->_dbi->isWikiPage($template)) {
60 $page = $request->_dbi->getPage($template);
61 $current = $page->getCurrentRevision();
62 $this->_content = $current->getPackedContent();
63 } elseif ($initial_content = $request->getArg('initial_content')) {
64 $this->_content = $initial_content;
65 $this->_redirect_to = $request->getArg('save_and_redirect_to');
69 header("Content-Type: text/html; charset=" . $GLOBALS['charset']);
72 function editPage () {
75 $tokens = &$this->tokens;
76 $tokens['PAGE_LOCKED_MESSAGE'] = '';
77 $tokens['CONCURRENT_UPDATE_MESSAGE'] = '';
79 if (isset($this->request->args['pref']['editWidth'])
80 and ($this->request->getPref('editWidth') != $this->request->args['pref']['editWidth'])) {
81 $this->request->_prefs->set('editWidth', $this->request->args['pref']['editWidth']);
83 if (isset($this->request->args['pref']['editHeight'])
84 and ($this->request->getPref('editHeight') != $this->request->args['pref']['editHeight'])) {
85 $this->request->_prefs->set('editHeight', $this->request->args['pref']['editHeight']);
88 if (! $this->canEdit()) {
89 if ($this->isInitialEdit())
90 return $this->viewSource();
91 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
93 elseif ($this->request->getArg('save_and_redirect_to') != "") {
94 if (ENABLE_CAPTCHA && $this->Captcha->Failed()) {
95 $this->tokens['PAGE_LOCKED_MESSAGE'] =
96 HTML::p(HTML::h1($this->Captcha->failed_msg));
98 elseif ( $this->savePage()) {
100 $this->request->redirect(WikiURL($this->request->getArg('save_and_redirect_to')));
101 return true; // Page saved.
105 elseif ($this->editaction == 'save') {
106 if (ENABLE_CAPTCHA && $this->Captcha->Failed()) {
107 $this->tokens['PAGE_LOCKED_MESSAGE'] =
108 HTML::p(HTML::h1($this->Captcha->failed_msg));
110 elseif ($this->savePage()) {
111 return true; // Page saved.
118 if ($saveFailed and $this->isConcurrentUpdate())
120 // Get the text of the original page, and the two conflicting edits
121 // The diff3 class takes arrays as input. So retrieve content as
122 // an array, or convert it as necesary.
123 $orig = $this->page->getRevision($this->_currentVersion);
124 // FIXME: what if _currentVersion has be deleted?
125 $orig_content = $orig->getContent();
126 $this_content = explode("\n", $this->_content);
127 $other_content = $this->current->getContent();
128 include_once("lib/diff3.php");
129 $diff = new diff3($orig_content, $this_content, $other_content);
130 $output = $diff->merged_output(_("Your version"), _("Other version"));
131 // Set the content of the textarea to the merged diff
132 // output, and update the version
133 $this->_content = implode ("\n", $output);
134 $this->_currentVersion = $this->current->getVersion();
135 $this->version = $this->_currentVersion;
136 $unresolved = $diff->ConflictingBlocks;
137 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage($unresolved);
138 } elseif ($saveFailed && !$this->_isSpam) {
139 $tokens['CONCURRENT_UPDATE_MESSAGE'] =
140 HTML(HTML::h2(_("Some internal editing error")),
141 HTML::p(_("Your are probably trying to edit/create an invalid version of this page.")),
142 HTML::p(HTML::em(_("&version=-1 might help."))));
145 if ($this->editaction == 'edit_convert')
146 $tokens['PREVIEW_CONTENT'] = $this->getConvertedPreview();
147 if ($this->editaction == 'preview')
148 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
150 // FIXME: NOT_CURRENT_MESSAGE?
151 $tokens = array_merge($tokens, $this->getFormElements());
153 if (ENABLE_EDIT_TOOLBAR and !ENABLE_WYSIWYG) {
154 include_once("lib/EditToolbar.php");
155 $toolbar = new EditToolbar();
156 $tokens = array_merge($tokens, $toolbar->getTokens());
159 return $this->output('editpage', _("Edit: %s"));
162 function output ($template, $title_fs) {
164 $selected = &$this->selected;
165 $current = &$this->current;
167 if ($selected && $selected->getVersion() != $current->getVersion()) {
169 $pagelink = WikiLink($selected);
173 $pagelink = WikiLink($this->page);
176 $title = new FormattedText ($title_fs, $pagelink);
177 // not for dumphtml or viewsource
178 if (ENABLE_WYSIWYG and $template == 'editpage') {
179 $WikiTheme->addMoreHeaders($this->WysiwygEdit->Head());
180 //$tokens['PAGE_SOURCE'] = $this->WysiwygEdit->ConvertBefore($this->_content);
182 $template = Template($template, $this->tokens);
183 GeneratePage($template, $title, $rev);
188 function viewSource () {
189 assert($this->isInitialEdit());
190 assert($this->selected);
192 $this->tokens['PAGE_SOURCE'] = $this->_content;
193 $this->tokens['HIDDEN_INPUTS'] = HiddenInputs($this->request->getArgs());
194 return $this->output('viewsource', _("View Source: %s"));
197 function updateLock() {
198 if ((bool)$this->page->get('locked') == (bool)$this->locked)
199 return false; // Not changed.
201 if (!$this->user->isAdmin()) {
202 // FIXME: some sort of message
203 return false; // not allowed.
206 $this->page->set('locked', (bool)$this->locked);
207 $this->tokens['LOCK_CHANGED_MSG']
208 = $this->locked ? _("Page now locked.") : _("Page now unlocked.");
210 return true; // lock changed.
213 function savePage () {
214 $request = &$this->request;
216 if ($this->isUnchanged()) {
217 // Allow admin lock/unlock even if
218 // no text changes were made.
219 if ($this->updateLock()) {
220 $dbi = $request->getDbh();
223 // Save failed. No changes made.
224 $this->_redirectToBrowsePage();
225 // user will probably not see the rest of this...
226 include_once('lib/display.php');
227 // force browse of current version:
228 $request->setArg('version', false);
229 displayPage($request, 'nochanges');
233 if ($this->isSpam()) {
234 $this->_isSpam = true;
237 // Save failed. No changes made.
238 $this->_redirectToBrowsePage();
239 // user will probably not see the rest of this...
240 include_once('lib/display.php');
241 // force browse of current version:
242 $request->setArg('version', false);
243 displayPage($request, 'nochanges');
248 $page = &$this->page;
250 // Include any meta-data from original page version which
251 // has not been explicitly updated.
252 // (Except don't propagate pgsrc_version --- moot for now,
253 // because at present it never gets into the db...)
254 $meta = $this->selected->getMetaData();
255 unset($meta['pgsrc_version']);
256 $meta = array_merge($meta, $this->meta);
259 $this->_content = $this->getContent();
260 $newrevision = $page->save($this->_content,
263 : $this->_currentVersion + 1,
266 if (!isa($newrevision, 'WikiDB_PageRevision')) {
267 // Save failed. (Concurrent updates).
271 // New contents successfully saved...
274 // Clean out archived versions of this page.
275 include_once('lib/ArchiveCleaner.php');
276 $cleaner = new ArchiveCleaner($GLOBALS['ExpireParams']);
277 $cleaner->cleanPageRevisions($page);
279 /* generate notification emails done in WikiDB::save to catch all direct calls
282 // look at the errorstack
283 $errors = $GLOBALS['ErrorManager']->_postponed_errors;
284 $warnings = $GLOBALS['ErrorManager']->getPostponedErrorsAsHTML();
285 $GLOBALS['ErrorManager']->_postponed_errors = $errors;
287 $dbi = $request->getDbh();
291 if (empty($warnings->_content) && ! $WikiTheme->getImageURL('signature')) {
292 // Do redirect to browse page if no signature has
293 // been defined. In this case, the user will most
294 // likely not see the rest of the HTML we generate
296 $this->_redirectToBrowsePage();
299 // Force browse of current page version.
300 $request->setArg('version', false);
301 //$request->setArg('action', false);
303 $template = Template('savepage', $this->tokens);
304 $template->replace('CONTENT', $newrevision->getTransformedContent());
305 if (!empty($warnings->_content))
306 $template->replace('WARNINGS', $warnings);
308 $pagelink = WikiLink($page);
310 GeneratePage($template, fmt("Saved: %s", $pagelink), $newrevision);
314 function isConcurrentUpdate () {
315 assert($this->current->getVersion() >= $this->_currentVersion);
316 return $this->current->getVersion() != $this->_currentVersion;
319 function canEdit () {
320 return !$this->page->get('locked') || $this->user->isAdmin();
323 function isInitialEdit () {
324 return $this->_initialEdit;
327 function isUnchanged () {
328 $current = &$this->current;
330 if ($this->meta['markup'] != $current->get('markup'))
333 return $this->_content == $current->getPackedContent();
337 * Handle AntiSpam here. How? http://wikiblacklist.blogspot.com/
338 * Need to check dynamically some blacklist wikipage settings
339 * (plugin WikiAccessRestrictions) and some static blacklist.
341 * Always: More then 20 new external links
342 * ENABLE_SPAMASSASSIN: content patterns by babycart (only php >= 4.3 for now)
343 * ENABLE_SPAMBLOCKLIST: IP blacklist, domain blacklist, url patterns
346 $current = &$this->current;
347 $request = &$this->request;
349 $oldtext = $current->getPackedContent();
350 $newtext =& $this->_content;
352 // FIXME: in longer texts the NUM_SPAM_LINKS number should be increased.
353 // better use a certain text : link ratio.
355 // 1. Not more then 20 new external links
356 if ($this->numLinks($newtext) - $this->numLinks($oldtext) >= NUM_SPAM_LINKS) {
357 // TODO: mail the admin?
358 $this->tokens['PAGE_LOCKED_MESSAGE'] =
359 HTML($this->getSpamMessage(),
360 HTML::p(HTML::strong(_("Too many external links."))));
363 // 2. external babycart (SpamAssassin) check
364 // This will probably prevent from discussing sex or viagra related topics. So beware.
365 if (ENABLE_SPAMASSASSIN) {
366 $user = $request->getUser();
367 include_once("lib/spam_babycart.php");
368 if ($babycart = check_babycart($newtext, $request->get("REMOTE_ADDR"),
370 // TODO: mail the admin
371 if (is_array($babycart))
372 $this->tokens['PAGE_LOCKED_MESSAGE'] =
373 HTML($this->getSpamMessage(),
374 HTML::p(HTML::em(_("SpamAssassin reports: ",
375 join("\n", $babycart)))));
379 // 3. extract (new) links and check surbl for blocked domains
380 if (ENABLE_SPAMBLOCKLIST and $this->numLinks($newtext)) {
381 include_once("lib/SpamBlocklist.php");
382 include_once("lib/InlineParser.php");
383 $parsed = TransformLinks($newtext);
384 foreach ($parsed->_content as $link) {
385 if (isa($link, 'Cached_ExternalLink')) {
386 $uri = $link->_getURL($this->page->getName());
387 if ($res = IsBlackListed($uri)) {
388 // TODO: mail the admin
389 $this->tokens['PAGE_LOCKED_MESSAGE'] =
390 HTML($this->getSpamMessage(),
391 HTML::p(HTML::strong(_("External links contain blocked domains:")),
392 HTML::ul(HTML::li(sprintf(_("%s is listed at %s"),
393 $res[2], $res[0])))));
403 /** Number of external links in the wikitext
405 function numLinks(&$text) {
406 return substr_count($text, "http://") + substr_count($text, "https://");
409 /** Header of the Anti Spam message
411 function getSpamMessage () {
413 HTML(HTML::h2(_("Spam Prevention")),
414 HTML::p(_("This page edit seems to contain spam and was therefore not saved."),
416 _("Sorry for the inconvenience.")),
420 function getPreview () {
421 include_once('lib/PageType.php');
422 $this->_content = $this->getContent();
423 return new TransformedText($this->page, $this->_content, $this->meta);
426 function getConvertedPreview () {
427 include_once('lib/PageType.php');
428 $this->_content = $this->getContent();
429 $this->meta['markup'] = 2.0;
430 $this->_content = ConvertOldMarkup($this->_content);
431 return new TransformedText($this->page, $this->_content, $this->meta);
434 // possibly convert HTMLAREA content back to Wiki markup
435 function getContent () {
436 if (ENABLE_WYSIWYG) {
437 // don't store everything as html
438 if (!USE_DEFAULT_PAGETYPE_HTML) {
439 $xml_output = $this->WysiwygEdit->ConvertAfter($this->_content);
440 $this->_content = join("", $xml_output->_content);
442 $this->meta['pagetype'] = 'html';
444 return $this->_content;
446 return $this->_content;
450 function getLockedMessage () {
452 HTML(HTML::h2(_("Page Locked")),
453 HTML::p(_("This page has been locked by the administrator so your changes can not be saved.")),
454 HTML::p(_("(Copy your changes to the clipboard. You can try editing a different page or save your text in a text editor.)")),
455 HTML::p(_("Sorry for the inconvenience.")));
458 function getConflictMessage ($unresolved = false) {
460 xgettext only knows about c/c++ line-continuation strings
461 it does not know about php's dot operator.
462 We want to translate this entire paragraph as one string, of course.
465 //$re_edit_link = Button('edit', _("Edit the new version"), $this->page);
468 $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.",
469 "<<<<<<< ". _("Your version"),
470 ">>>>>>> ". _("Other version")));
472 $message = HTML::p(_("Please check it through before saving."));
476 /*$steps = HTML::ol(HTML::li(_("Copy your changes to the clipboard or to another temporary place (e.g. text editor).")),
477 HTML::li(fmt("%s of the page. You should now see the most current version of the page. Your changes are no longer there.",
479 HTML::li(_("Make changes to the file again. Paste your additions from the clipboard (or text editor).")),
480 HTML::li(_("Save your updated changes.")));
483 HTML(HTML::h2(_("Conflicting Edits!")),
484 HTML::p(_("In the time since you started editing this page, another user has saved a new version of it.")),
485 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.")),
490 function getTextArea () {
491 $request = &$this->request;
493 $readonly = ! $this->canEdit(); // || $this->isConcurrentUpdate();
495 // WYSIWYG will need two pagetypes: raw wikitest and converted html
496 if (ENABLE_WYSIWYG) {
497 $this->_wikicontent = $this->_content;
498 $this->_content = $this->WysiwygEdit->ConvertBefore($this->_content);
499 // $this->getPreview();
500 //$this->_htmlcontent = $this->_content->asXML();
503 $textarea = HTML::textarea(array('class'=> 'wikiedit',
504 'name' => 'edit[content]',
505 'id' => 'edit:content',
506 'rows' => $request->getPref('editHeight'),
507 'cols' => $request->getPref('editWidth'),
508 'readonly' => (bool) $readonly),
510 /** <textarea wrap="virtual"> is not valid XHTML but Netscape 4 requires it
511 * to wrap long lines.
514 $textarea->setAttr('wrap', 'virtual');
515 if (ENABLE_WYSIWYG) {
516 return $this->WysiwygEdit->Textarea($textarea, $this->_wikicontent,
517 $textarea->getAttr('name'));
522 function getFormElements () {
524 $request = &$this->request;
525 $page = &$this->page;
527 $h = array('action' => 'edit',
528 'pagename' => $page->getName(),
529 'version' => $this->version,
530 'edit[pagetype]' => $this->meta['pagetype'],
531 'edit[current_version]' => $this->_currentVersion);
533 $el['HIDDEN_INPUTS'] = HiddenInputs($h);
534 $el['EDIT_TEXTAREA'] = $this->getTextArea();
535 if ( ENABLE_CAPTCHA ) {
536 $el = array_merge($el, $this->Captcha->getFormElements());
539 = HTML::input(array('type' => 'text',
540 'class' => 'wikitext',
541 'id' => 'edit:summary',
542 'name' => 'edit[summary]',
545 'value' => $this->meta['summary']));
547 = HTML::input(array('type' => 'checkbox',
548 'name' => 'edit[minor_edit]',
549 'id' => 'edit:minor_edit',
550 'checked' => (bool) $this->meta['is_minor_edit']));
552 = HTML::input(array('type' => 'checkbox',
553 'name' => 'edit[markup]',
555 'checked' => $this->meta['markup'] < 2.0,
556 'id' => 'useOldMarkup',
557 'onclick' => 'showOldMarkupRules(this.checked)'));
558 $el['OLD_MARKUP_CONVERT'] = ($this->meta['markup'] < 2.0)
559 ? Button('submit:edit[edit_convert]', _("Convert"), 'wikiaction') : '';
561 = HTML::input(array('type' => 'checkbox',
562 'name' => 'edit[locked]',
563 'id' => 'edit:locked',
564 'disabled' => (bool) !$this->user->isadmin(),
565 'checked' => (bool) $this->locked));
567 $el['PREVIEW_B'] = Button('submit:edit[preview]', _("Preview"),
570 //if (!$this->isConcurrentUpdate() && $this->canEdit())
571 $el['SAVE_B'] = Button('submit:edit[save]', _("Save"), 'wikiaction');
573 $el['IS_CURRENT'] = $this->version == $this->current->getVersion();
576 = HTML::input(array('type' => 'text',
579 'class' => "numeric",
580 'name' => 'pref[editWidth]',
581 'id' => 'pref:editWidth',
582 'value' => $request->getPref('editWidth'),
583 'onchange' => 'this.form.submit();'));
585 = HTML::input(array('type' => 'text',
588 'class' => "numeric",
589 'name' => 'pref[editHeight]',
590 'id' => 'pref:editHeight',
591 'value' => $request->getPref('editHeight'),
592 'onchange' => 'this.form.submit();'));
593 $el['SEP'] = $WikiTheme->getButtonSeparator();
594 $el['AUTHOR_MESSAGE'] = fmt("Author will be logged as %s.",
595 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);
763 function getConflictMessage () {
764 $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.",
767 HTML::p(_("Please check it through before saving."))));
773 $Log: not supported by cvs2svn $
774 Revision 1.101 2005/10/30 16:12:28 rurban
775 simplify viewsource tokens
777 Revision 1.100 2005/10/30 14:20:42 rurban
778 move Captcha specific vars and methods into a Captcha object
779 randomize Captcha chars positions and angles (smoothly)
781 Revision 1.99 2005/10/29 08:21:58 rurban
782 ENABLE_SPAMBLOCKLIST:
783 Check for links to blocked external tld domains in new edits, against
784 multi.surbl.org and bl.spamcop.net.
786 Revision 1.98 2005/10/10 19:37:04 rurban
787 change USE_HTMLAREA to ENABLE WYSIWYG, add NUM_SPAM_LINKS=20
789 Revision 1.97 2005/09/26 06:32:22 rurban
790 [] is forbidden in id tags. Renamed to use :
792 Revision 1.96 2005/05/06 17:54:22 rurban
793 silence Preview warnings for PAGE_LOCKED_MESSAGE, CONCURRENT_UPDATE_MESSAGE (thanks to schorni)
795 Revision 1.95 2005/04/25 20:17:14 rurban
796 captcha feature by Benjamin Drieu. Patch #1110699
798 Revision 1.94 2005/02/28 20:23:31 rurban
801 Revision 1.93 2005/02/27 19:31:52 rurban
802 hack: display errorstack without sideeffects (save and restore)
804 Revision 1.92 2005/01/29 20:37:21 rurban
805 no edit toolbar at all if ENABLE_EDITTOOLBAR = false
807 Revision 1.91 2005/01/25 07:05:49 rurban
808 extract toolbar code, support new tags to get rid of php inside templates
810 Revision 1.90 2005/01/22 12:46:15 rurban
811 fix oldmakrup button label
812 update pref[edit*] settings
814 Revision 1.89 2005/01/21 14:07:49 rurban
817 Revision 1.88 2004/12/17 16:39:03 rurban
820 Revision 1.87 2004/12/16 18:28:05 rurban
821 keep wikiblog summary = page title
823 Revision 1.86 2004/12/11 14:50:15 rurban
824 new edit_convert button, to get rid of old markup eventually
826 Revision 1.85 2004/12/06 19:49:56 rurban
827 enable action=remove which is undoable and seeable in RecentChanges: ADODB ony for now.
828 renamed delete_page to purge_page.
829 enable action=edit&version=-1 to force creation of a new version.
830 added BABYCART_PATH config
831 fixed magiqc in adodb.inc.php
834 Revision 1.84 2004/12/04 12:58:26 rurban
835 enable babycart Blog::SpamAssassin module on ENABLE_SPAMASSASSIN=true
836 (currently only for php >= 4.3.0)
838 Revision 1.83 2004/12/04 11:55:39 rurban
839 First simple AntiSpam prevention:
840 No more than 20 new http:// links allowed
842 Revision 1.82 2004/11/30 22:21:56 rurban
843 changed gif to optimized (pngout) png
845 Revision 1.81 2004/11/29 17:57:27 rurban
846 translated pulldown buttons
848 Revision 1.80 2004/11/25 17:20:51 rurban
849 and again a couple of more native db args: backlinks
851 Revision 1.79 2004/11/21 11:59:20 rurban
852 remove final \n to be ob_cache independent
854 Revision 1.78 2004/11/16 17:57:45 rurban
855 fix search&replace button
856 use new addTagButton machinery
857 new showPulldown for categories, TODO: in a seperate request
859 Revision 1.77 2004/11/15 15:52:35 rurban
862 Revision 1.76 2004/11/15 15:37:34 rurban
864 don't use document.write for replace, otherwise self.opener is not defined.
866 Revision 1.75 2004/09/16 08:00:52 rurban
869 Revision 1.74 2004/07/03 07:36:28 rurban
870 do not get unneccessary content
872 Revision 1.73 2004/06/16 21:23:44 rurban
873 fixed non-object fatal #215
875 Revision 1.72 2004/06/14 11:31:37 rurban
876 renamed global $Theme to $WikiTheme (gforge nameclash)
877 inherit PageList default options from PageList
878 default sortby=pagename
879 use options in PageList_Selectable (limit, sortby, ...)
880 added action revert, with button at action=diff
881 added option regex to WikiAdminSearchReplace
883 Revision 1.71 2004/06/03 18:06:29 rurban
884 fix file locking issues (only needed on write)
885 fixed immediate LANG and THEME in-session updates if not stored in prefs
886 advanced editpage toolbars (search & replace broken)
888 Revision 1.70 2004/06/02 20:47:47 rurban
889 dont use the wikiaction class
891 Revision 1.69 2004/06/02 10:17:56 rurban
892 integrated search/replace into toolbar
893 added save+preview buttons
895 Revision 1.68 2004/06/01 15:28:00 rurban
896 AdminUser only ADMIN_USER not member of Administrators
897 some RateIt improvements by dfrankow
900 Revision _1.6 2004/05/26 15:48:00 syilek
901 fixed problem with creating page with slashes from one true page
903 Revision _1.5 2004/05/25 16:51:53 syilek
904 added ability to create a page from the category page and not have to edit it
906 Revision 1.67 2004/05/27 17:49:06 rurban
907 renamed DB_Session to DbSession (in CVS also)
908 added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
909 remove leading slash in error message
910 added force_unlock parameter to File_Passwd (no return on stale locks)
911 fixed adodb session AffectedRows
912 added FileFinder helpers to unify local filenames and DATA_PATH names
913 editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
915 Revision 1.66 2004/04/29 23:25:12 rurban
916 re-ordered locale init (as in 1.3.9)
917 fixed loadfile with subpages, and merge/restore anyway
920 Revision 1.65 2004/04/18 01:11:52 rurban
921 more numeric pagename fixes.
922 fixed action=upload with merge conflict warnings.
923 charset changed from constant to global (dynamic utf-8 switching)
925 Revision 1.64 2004/04/06 19:48:56 rurban
926 temp workaround for action=edit AddComment form
928 Revision 1.63 2004/03/24 19:39:02 rurban
929 php5 workaround code (plus some interim debugging code in XmlElement)
930 php5 doesn't work yet with the current XmlElement class constructors,
931 WikiUserNew does work better than php4.
932 rewrote WikiUserNew user upgrading to ease php5 update
933 fixed pref handling in WikiUserNew
934 added Email Notification
935 added simple Email verification
936 removed emailVerify userpref subclass: just a email property
937 changed pref binary storage layout: numarray => hash of non default values
938 print optimize message only if really done.
939 forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
940 prefs should be stored in db or homepage, besides the current session.
942 Revision 1.62 2004/03/17 18:41:05 rurban
943 initial_content and template support for CreatePage
945 Revision 1.61 2004/03/12 20:59:17 rurban
946 important cookie fix by Konstantin Zadorozhny
947 new editpage feature: JS_SEARCHREPLACE
949 Revision 1.60 2004/02/15 21:34:37 rurban
950 PageList enhanced and improved.
951 fixed new WikiAdmin... plugins
952 editpage, Theme with exp. htmlarea framework
953 (htmlarea yet committed, this is really questionable)
954 WikiUser... code with better session handling for prefs
955 enhanced UserPreferences (again)
956 RecentChanges for show_deleted: how should pages be deleted then?
958 Revision 1.59 2003/12/07 20:35:26 carstenklapp
959 Bugfix: Concurrent updates broken since after 1.3.4 release: Fatal
960 error: Call to undefined function: gettransformedcontent() in
961 /home/groups/p/ph/phpwiki/htdocs/phpwiki2/lib/editpage.php on line
964 Revision 1.58 2003/03/10 18:25:22 dairiki
965 Bug/typo fix. If you use the edit page to un/lock a page, it
966 failed with: Fatal error: Call to a member function on a
967 non-object in editpage.php on line 136
969 Revision 1.57 2003/02/26 03:40:22 dairiki
970 New action=create. Essentially the same as action=edit, except that if the
971 page already exists, it falls back to action=browse.
973 This is for use in the "question mark" links for unknown wiki words
974 to avoid problems and confusion when following links from stale pages.
975 (If the "unknown page" has been created in the interim, the user probably
976 wants to view the page before editing it.)
978 Revision 1.56 2003/02/21 18:07:14 dairiki
979 Minor, nitpicky, currently inconsequential changes.
981 Revision 1.55 2003/02/21 04:10:58 dairiki
982 Fixes for new cached markup.
983 Some minor code cleanups.
985 Revision 1.54 2003/02/16 19:47:16 dairiki
986 Update WikiDB timestamp when editing or deleting pages.
988 Revision 1.53 2003/02/15 23:20:27 dairiki
989 Redirect back to browse current version of page upon save,
990 even when no changes were made.
992 Revision 1.52 2003/01/03 22:22:00 carstenklapp
993 Minor adjustments to diff block markers ("<<<<<<<"). Source reformatting.
995 Revision 1.51 2003/01/03 02:43:26 carstenklapp
996 New class LoadFileConflictPageEditor, for merging / comparing a loaded
997 pgsrc file with an existing page.
1004 // c-basic-offset: 4
1005 // c-hanging-comment-ender-p: nil
1006 // indent-tabs-mode: nil