2 rcs_id('$Id: editpage.php,v 1.101 2005-10-30 16:12:28 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 $this->tokens['HIDDEN_INPUTS'] = HiddenInputs($this->request->getArgs());
199 return $this->output('viewsource', _("View Source: %s"));
202 function updateLock() {
203 if ((bool)$this->page->get('locked') == (bool)$this->locked)
204 return false; // Not changed.
206 if (!$this->user->isAdmin()) {
207 // FIXME: some sort of message
208 return false; // not allowed.
211 $this->page->set('locked', (bool)$this->locked);
212 $this->tokens['LOCK_CHANGED_MSG']
213 = $this->locked ? _("Page now locked.") : _("Page now unlocked.");
215 return true; // lock changed.
218 function savePage () {
219 $request = &$this->request;
221 if ($this->isUnchanged()) {
222 // Allow admin lock/unlock even if
223 // no text changes were made.
224 if ($this->updateLock()) {
225 $dbi = $request->getDbh();
228 // Save failed. No changes made.
229 $this->_redirectToBrowsePage();
230 // user will probably not see the rest of this...
231 include_once('lib/display.php');
232 // force browse of current version:
233 $request->setArg('version', false);
234 displayPage($request, 'nochanges');
238 if ($this->isSpam()) {
239 $this->_isSpam = true;
242 // Save failed. No changes made.
243 $this->_redirectToBrowsePage();
244 // user will probably not see the rest of this...
245 include_once('lib/display.php');
246 // force browse of current version:
247 $request->setArg('version', false);
248 displayPage($request, 'nochanges');
253 $page = &$this->page;
255 // Include any meta-data from original page version which
256 // has not been explicitly updated.
257 // (Except don't propagate pgsrc_version --- moot for now,
258 // because at present it never gets into the db...)
259 $meta = $this->selected->getMetaData();
260 unset($meta['pgsrc_version']);
261 $meta = array_merge($meta, $this->meta);
264 $this->_content = $this->getContent();
265 $newrevision = $page->save($this->_content,
268 : $this->_currentVersion + 1,
271 if (!isa($newrevision, 'WikiDB_PageRevision')) {
272 // Save failed. (Concurrent updates).
276 // New contents successfully saved...
279 // Clean out archived versions of this page.
280 include_once('lib/ArchiveCleaner.php');
281 $cleaner = new ArchiveCleaner($GLOBALS['ExpireParams']);
282 $cleaner->cleanPageRevisions($page);
284 /* generate notification emails done in WikiDB::save to catch all direct calls
287 // look at the errorstack
288 $errors = $GLOBALS['ErrorManager']->_postponed_errors;
289 $warnings = $GLOBALS['ErrorManager']->getPostponedErrorsAsHTML();
290 $GLOBALS['ErrorManager']->_postponed_errors = $errors;
292 $dbi = $request->getDbh();
296 if (empty($warnings->_content) && ! $WikiTheme->getImageURL('signature')) {
297 // Do redirect to browse page if no signature has
298 // been defined. In this case, the user will most
299 // likely not see the rest of the HTML we generate
301 $this->_redirectToBrowsePage();
304 // Force browse of current page version.
305 $request->setArg('version', false);
306 //$request->setArg('action', false);
308 $template = Template('savepage', $this->tokens);
309 $template->replace('CONTENT', $newrevision->getTransformedContent());
310 if (!empty($warnings->_content))
311 $template->replace('WARNINGS', $warnings);
313 $pagelink = WikiLink($page);
315 GeneratePage($template, fmt("Saved: %s", $pagelink), $newrevision);
319 function isConcurrentUpdate () {
320 assert($this->current->getVersion() >= $this->_currentVersion);
321 return $this->current->getVersion() != $this->_currentVersion;
324 function canEdit () {
325 return !$this->page->get('locked') || $this->user->isAdmin();
328 function isInitialEdit () {
329 return $this->_initialEdit;
332 function isUnchanged () {
333 $current = &$this->current;
335 if ($this->meta['markup'] != $current->get('markup'))
338 return $this->_content == $current->getPackedContent();
342 * Handle AntiSpam here. How? http://wikiblacklist.blogspot.com/
343 * Need to check dynamically some blacklist wikipage settings
344 * (plugin WikiAccessRestrictions) and some static blacklist.
346 * Always: More then 20 new external links
347 * ENABLE_SPAMASSASSIN: content patterns by babycart (only php >= 4.3 for now)
348 * ENABLE_SPAMBLOCKLIST: IP blacklist, domain blacklist, url patterns
351 $current = &$this->current;
352 $request = &$this->request;
354 $oldtext = $current->getPackedContent();
355 $newtext =& $this->_content;
357 // FIXME: in longer texts the NUM_SPAM_LINKS number should be increased.
358 // better use a certain text : link ratio.
360 // 1. Not more then 20 new external links
361 if ($this->numLinks($newtext) - $this->numLinks($oldtext) >= NUM_SPAM_LINKS) {
362 // TODO: mail the admin?
363 $this->tokens['PAGE_LOCKED_MESSAGE'] =
364 HTML($this->getSpamMessage(),
365 HTML::p(HTML::strong(_("Too many external links."))));
368 // 2. external babycart (SpamAssassin) check
369 // This will probably prevent from discussing sex or viagra related topics. So beware.
370 if (ENABLE_SPAMASSASSIN) {
371 $user = $request->getUser();
372 include_once("lib/spam_babycart.php");
373 if ($babycart = check_babycart($newtext, $request->get("REMOTE_ADDR"),
375 // TODO: mail the admin
376 if (is_array($babycart))
377 $this->tokens['PAGE_LOCKED_MESSAGE'] =
378 HTML($this->getSpamMessage(),
379 HTML::p(HTML::em(_("SpamAssassin reports: ",
380 join("\n", $babycart)))));
384 // 3. extract (new) links and check surbl for blocked domains
385 if (ENABLE_SPAMBLOCKLIST and $this->numLinks($newtext)) {
386 include_once("lib/SpamBlocklist.php");
387 include_once("lib/InlineParser.php");
388 $parsed = TransformLinks($newtext);
389 foreach ($parsed->_content as $link) {
390 if (isa($link, 'Cached_ExternalLink')) {
391 $uri = $link->_getURL($this->page->getName());
392 if ($res = IsBlackListed($uri)) {
393 // TODO: mail the admin
394 $this->tokens['PAGE_LOCKED_MESSAGE'] =
395 HTML($this->getSpamMessage(),
396 HTML::p(HTML::strong(_("External links contain blocked domains:")),
397 HTML::ul(HTML::li(sprintf(_("%s is listed at %s"),
398 $res[2], $res[0])))));
408 /** Number of external links in the wikitext
410 function numLinks(&$text) {
411 return substr_count($text, "http://") + substr_count($text, "https://");
414 /** Header of the Anti Spam message
416 function getSpamMessage () {
418 HTML(HTML::h2(_("Spam Prevention")),
419 HTML::p(_("This page edit seems to contain spam and was therefore not saved."),
421 _("Sorry for the inconvenience.")),
425 function getPreview () {
426 include_once('lib/PageType.php');
427 $this->_content = $this->getContent();
428 return new TransformedText($this->page, $this->_content, $this->meta);
431 function getConvertedPreview () {
432 include_once('lib/PageType.php');
433 $this->_content = $this->getContent();
434 $this->meta['markup'] = 2.0;
435 $this->_content = ConvertOldMarkup($this->_content);
436 return new TransformedText($this->page, $this->_content, $this->meta);
439 // possibly convert HTMLAREA content back to Wiki markup
440 function getContent () {
441 if (ENABLE_WYSIWYG) {
442 $xml_output = $this->WysiwygEdit->ConvertAfter($this->_content);
443 //$this->_content = join("", $xml_output->_content);
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->getPreview();
499 // $html = $this->getPreview();
500 // $this->_content = $html->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.100 2005/10/30 14:20:42 rurban
775 move Captcha specific vars and methods into a Captcha object
776 randomize Captcha chars positions and angles (smoothly)
778 Revision 1.99 2005/10/29 08:21:58 rurban
779 ENABLE_SPAMBLOCKLIST:
780 Check for links to blocked external tld domains in new edits, against
781 multi.surbl.org and bl.spamcop.net.
783 Revision 1.98 2005/10/10 19:37:04 rurban
784 change USE_HTMLAREA to ENABLE WYSIWYG, add NUM_SPAM_LINKS=20
786 Revision 1.97 2005/09/26 06:32:22 rurban
787 [] is forbidden in id tags. Renamed to use :
789 Revision 1.96 2005/05/06 17:54:22 rurban
790 silence Preview warnings for PAGE_LOCKED_MESSAGE, CONCURRENT_UPDATE_MESSAGE (thanks to schorni)
792 Revision 1.95 2005/04/25 20:17:14 rurban
793 captcha feature by Benjamin Drieu. Patch #1110699
795 Revision 1.94 2005/02/28 20:23:31 rurban
798 Revision 1.93 2005/02/27 19:31:52 rurban
799 hack: display errorstack without sideeffects (save and restore)
801 Revision 1.92 2005/01/29 20:37:21 rurban
802 no edit toolbar at all if ENABLE_EDITTOOLBAR = false
804 Revision 1.91 2005/01/25 07:05:49 rurban
805 extract toolbar code, support new tags to get rid of php inside templates
807 Revision 1.90 2005/01/22 12:46:15 rurban
808 fix oldmakrup button label
809 update pref[edit*] settings
811 Revision 1.89 2005/01/21 14:07:49 rurban
814 Revision 1.88 2004/12/17 16:39:03 rurban
817 Revision 1.87 2004/12/16 18:28:05 rurban
818 keep wikiblog summary = page title
820 Revision 1.86 2004/12/11 14:50:15 rurban
821 new edit_convert button, to get rid of old markup eventually
823 Revision 1.85 2004/12/06 19:49:56 rurban
824 enable action=remove which is undoable and seeable in RecentChanges: ADODB ony for now.
825 renamed delete_page to purge_page.
826 enable action=edit&version=-1 to force creation of a new version.
827 added BABYCART_PATH config
828 fixed magiqc in adodb.inc.php
831 Revision 1.84 2004/12/04 12:58:26 rurban
832 enable babycart Blog::SpamAssassin module on ENABLE_SPAMASSASSIN=true
833 (currently only for php >= 4.3.0)
835 Revision 1.83 2004/12/04 11:55:39 rurban
836 First simple AntiSpam prevention:
837 No more than 20 new http:// links allowed
839 Revision 1.82 2004/11/30 22:21:56 rurban
840 changed gif to optimized (pngout) png
842 Revision 1.81 2004/11/29 17:57:27 rurban
843 translated pulldown buttons
845 Revision 1.80 2004/11/25 17:20:51 rurban
846 and again a couple of more native db args: backlinks
848 Revision 1.79 2004/11/21 11:59:20 rurban
849 remove final \n to be ob_cache independent
851 Revision 1.78 2004/11/16 17:57:45 rurban
852 fix search&replace button
853 use new addTagButton machinery
854 new showPulldown for categories, TODO: in a seperate request
856 Revision 1.77 2004/11/15 15:52:35 rurban
859 Revision 1.76 2004/11/15 15:37:34 rurban
861 don't use document.write for replace, otherwise self.opener is not defined.
863 Revision 1.75 2004/09/16 08:00:52 rurban
866 Revision 1.74 2004/07/03 07:36:28 rurban
867 do not get unneccessary content
869 Revision 1.73 2004/06/16 21:23:44 rurban
870 fixed non-object fatal #215
872 Revision 1.72 2004/06/14 11:31:37 rurban
873 renamed global $Theme to $WikiTheme (gforge nameclash)
874 inherit PageList default options from PageList
875 default sortby=pagename
876 use options in PageList_Selectable (limit, sortby, ...)
877 added action revert, with button at action=diff
878 added option regex to WikiAdminSearchReplace
880 Revision 1.71 2004/06/03 18:06:29 rurban
881 fix file locking issues (only needed on write)
882 fixed immediate LANG and THEME in-session updates if not stored in prefs
883 advanced editpage toolbars (search & replace broken)
885 Revision 1.70 2004/06/02 20:47:47 rurban
886 dont use the wikiaction class
888 Revision 1.69 2004/06/02 10:17:56 rurban
889 integrated search/replace into toolbar
890 added save+preview buttons
892 Revision 1.68 2004/06/01 15:28:00 rurban
893 AdminUser only ADMIN_USER not member of Administrators
894 some RateIt improvements by dfrankow
897 Revision _1.6 2004/05/26 15:48:00 syilek
898 fixed problem with creating page with slashes from one true page
900 Revision _1.5 2004/05/25 16:51:53 syilek
901 added ability to create a page from the category page and not have to edit it
903 Revision 1.67 2004/05/27 17:49:06 rurban
904 renamed DB_Session to DbSession (in CVS also)
905 added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
906 remove leading slash in error message
907 added force_unlock parameter to File_Passwd (no return on stale locks)
908 fixed adodb session AffectedRows
909 added FileFinder helpers to unify local filenames and DATA_PATH names
910 editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
912 Revision 1.66 2004/04/29 23:25:12 rurban
913 re-ordered locale init (as in 1.3.9)
914 fixed loadfile with subpages, and merge/restore anyway
917 Revision 1.65 2004/04/18 01:11:52 rurban
918 more numeric pagename fixes.
919 fixed action=upload with merge conflict warnings.
920 charset changed from constant to global (dynamic utf-8 switching)
922 Revision 1.64 2004/04/06 19:48:56 rurban
923 temp workaround for action=edit AddComment form
925 Revision 1.63 2004/03/24 19:39:02 rurban
926 php5 workaround code (plus some interim debugging code in XmlElement)
927 php5 doesn't work yet with the current XmlElement class constructors,
928 WikiUserNew does work better than php4.
929 rewrote WikiUserNew user upgrading to ease php5 update
930 fixed pref handling in WikiUserNew
931 added Email Notification
932 added simple Email verification
933 removed emailVerify userpref subclass: just a email property
934 changed pref binary storage layout: numarray => hash of non default values
935 print optimize message only if really done.
936 forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
937 prefs should be stored in db or homepage, besides the current session.
939 Revision 1.62 2004/03/17 18:41:05 rurban
940 initial_content and template support for CreatePage
942 Revision 1.61 2004/03/12 20:59:17 rurban
943 important cookie fix by Konstantin Zadorozhny
944 new editpage feature: JS_SEARCHREPLACE
946 Revision 1.60 2004/02/15 21:34:37 rurban
947 PageList enhanced and improved.
948 fixed new WikiAdmin... plugins
949 editpage, Theme with exp. htmlarea framework
950 (htmlarea yet committed, this is really questionable)
951 WikiUser... code with better session handling for prefs
952 enhanced UserPreferences (again)
953 RecentChanges for show_deleted: how should pages be deleted then?
955 Revision 1.59 2003/12/07 20:35:26 carstenklapp
956 Bugfix: Concurrent updates broken since after 1.3.4 release: Fatal
957 error: Call to undefined function: gettransformedcontent() in
958 /home/groups/p/ph/phpwiki/htdocs/phpwiki2/lib/editpage.php on line
961 Revision 1.58 2003/03/10 18:25:22 dairiki
962 Bug/typo fix. If you use the edit page to un/lock a page, it
963 failed with: Fatal error: Call to a member function on a
964 non-object in editpage.php on line 136
966 Revision 1.57 2003/02/26 03:40:22 dairiki
967 New action=create. Essentially the same as action=edit, except that if the
968 page already exists, it falls back to action=browse.
970 This is for use in the "question mark" links for unknown wiki words
971 to avoid problems and confusion when following links from stale pages.
972 (If the "unknown page" has been created in the interim, the user probably
973 wants to view the page before editing it.)
975 Revision 1.56 2003/02/21 18:07:14 dairiki
976 Minor, nitpicky, currently inconsequential changes.
978 Revision 1.55 2003/02/21 04:10:58 dairiki
979 Fixes for new cached markup.
980 Some minor code cleanups.
982 Revision 1.54 2003/02/16 19:47:16 dairiki
983 Update WikiDB timestamp when editing or deleting pages.
985 Revision 1.53 2003/02/15 23:20:27 dairiki
986 Redirect back to browse current version of page upon save,
987 even when no changes were made.
989 Revision 1.52 2003/01/03 22:22:00 carstenklapp
990 Minor adjustments to diff block markers ("<<<<<<<"). Source reformatting.
992 Revision 1.51 2003/01/03 02:43:26 carstenklapp
993 New class LoadFileConflictPageEditor, for merging / comparing a loaded
994 pgsrc file with an existing page.
1001 // c-basic-offset: 4
1002 // c-hanging-comment-ender-p: nil
1003 // indent-tabs-mode: nil