2 rcs_id('$Id: editpage.php,v 1.103 2005-10-31 17:09:13 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 (!WYSIWYG_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.102 2005/10/31 16:47:14 rurban
775 enable wysiwyg html converters
777 Revision 1.101 2005/10/30 16:12:28 rurban
778 simplify viewsource tokens
780 Revision 1.100 2005/10/30 14:20:42 rurban
781 move Captcha specific vars and methods into a Captcha object
782 randomize Captcha chars positions and angles (smoothly)
784 Revision 1.99 2005/10/29 08:21:58 rurban
785 ENABLE_SPAMBLOCKLIST:
786 Check for links to blocked external tld domains in new edits, against
787 multi.surbl.org and bl.spamcop.net.
789 Revision 1.98 2005/10/10 19:37:04 rurban
790 change USE_HTMLAREA to ENABLE WYSIWYG, add NUM_SPAM_LINKS=20
792 Revision 1.97 2005/09/26 06:32:22 rurban
793 [] is forbidden in id tags. Renamed to use :
795 Revision 1.96 2005/05/06 17:54:22 rurban
796 silence Preview warnings for PAGE_LOCKED_MESSAGE, CONCURRENT_UPDATE_MESSAGE (thanks to schorni)
798 Revision 1.95 2005/04/25 20:17:14 rurban
799 captcha feature by Benjamin Drieu. Patch #1110699
801 Revision 1.94 2005/02/28 20:23:31 rurban
804 Revision 1.93 2005/02/27 19:31:52 rurban
805 hack: display errorstack without sideeffects (save and restore)
807 Revision 1.92 2005/01/29 20:37:21 rurban
808 no edit toolbar at all if ENABLE_EDITTOOLBAR = false
810 Revision 1.91 2005/01/25 07:05:49 rurban
811 extract toolbar code, support new tags to get rid of php inside templates
813 Revision 1.90 2005/01/22 12:46:15 rurban
814 fix oldmakrup button label
815 update pref[edit*] settings
817 Revision 1.89 2005/01/21 14:07:49 rurban
820 Revision 1.88 2004/12/17 16:39:03 rurban
823 Revision 1.87 2004/12/16 18:28:05 rurban
824 keep wikiblog summary = page title
826 Revision 1.86 2004/12/11 14:50:15 rurban
827 new edit_convert button, to get rid of old markup eventually
829 Revision 1.85 2004/12/06 19:49:56 rurban
830 enable action=remove which is undoable and seeable in RecentChanges: ADODB ony for now.
831 renamed delete_page to purge_page.
832 enable action=edit&version=-1 to force creation of a new version.
833 added BABYCART_PATH config
834 fixed magiqc in adodb.inc.php
837 Revision 1.84 2004/12/04 12:58:26 rurban
838 enable babycart Blog::SpamAssassin module on ENABLE_SPAMASSASSIN=true
839 (currently only for php >= 4.3.0)
841 Revision 1.83 2004/12/04 11:55:39 rurban
842 First simple AntiSpam prevention:
843 No more than 20 new http:// links allowed
845 Revision 1.82 2004/11/30 22:21:56 rurban
846 changed gif to optimized (pngout) png
848 Revision 1.81 2004/11/29 17:57:27 rurban
849 translated pulldown buttons
851 Revision 1.80 2004/11/25 17:20:51 rurban
852 and again a couple of more native db args: backlinks
854 Revision 1.79 2004/11/21 11:59:20 rurban
855 remove final \n to be ob_cache independent
857 Revision 1.78 2004/11/16 17:57:45 rurban
858 fix search&replace button
859 use new addTagButton machinery
860 new showPulldown for categories, TODO: in a seperate request
862 Revision 1.77 2004/11/15 15:52:35 rurban
865 Revision 1.76 2004/11/15 15:37:34 rurban
867 don't use document.write for replace, otherwise self.opener is not defined.
869 Revision 1.75 2004/09/16 08:00:52 rurban
872 Revision 1.74 2004/07/03 07:36:28 rurban
873 do not get unneccessary content
875 Revision 1.73 2004/06/16 21:23:44 rurban
876 fixed non-object fatal #215
878 Revision 1.72 2004/06/14 11:31:37 rurban
879 renamed global $Theme to $WikiTheme (gforge nameclash)
880 inherit PageList default options from PageList
881 default sortby=pagename
882 use options in PageList_Selectable (limit, sortby, ...)
883 added action revert, with button at action=diff
884 added option regex to WikiAdminSearchReplace
886 Revision 1.71 2004/06/03 18:06:29 rurban
887 fix file locking issues (only needed on write)
888 fixed immediate LANG and THEME in-session updates if not stored in prefs
889 advanced editpage toolbars (search & replace broken)
891 Revision 1.70 2004/06/02 20:47:47 rurban
892 dont use the wikiaction class
894 Revision 1.69 2004/06/02 10:17:56 rurban
895 integrated search/replace into toolbar
896 added save+preview buttons
898 Revision 1.68 2004/06/01 15:28:00 rurban
899 AdminUser only ADMIN_USER not member of Administrators
900 some RateIt improvements by dfrankow
903 Revision _1.6 2004/05/26 15:48:00 syilek
904 fixed problem with creating page with slashes from one true page
906 Revision _1.5 2004/05/25 16:51:53 syilek
907 added ability to create a page from the category page and not have to edit it
909 Revision 1.67 2004/05/27 17:49:06 rurban
910 renamed DB_Session to DbSession (in CVS also)
911 added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
912 remove leading slash in error message
913 added force_unlock parameter to File_Passwd (no return on stale locks)
914 fixed adodb session AffectedRows
915 added FileFinder helpers to unify local filenames and DATA_PATH names
916 editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
918 Revision 1.66 2004/04/29 23:25:12 rurban
919 re-ordered locale init (as in 1.3.9)
920 fixed loadfile with subpages, and merge/restore anyway
923 Revision 1.65 2004/04/18 01:11:52 rurban
924 more numeric pagename fixes.
925 fixed action=upload with merge conflict warnings.
926 charset changed from constant to global (dynamic utf-8 switching)
928 Revision 1.64 2004/04/06 19:48:56 rurban
929 temp workaround for action=edit AddComment form
931 Revision 1.63 2004/03/24 19:39:02 rurban
932 php5 workaround code (plus some interim debugging code in XmlElement)
933 php5 doesn't work yet with the current XmlElement class constructors,
934 WikiUserNew does work better than php4.
935 rewrote WikiUserNew user upgrading to ease php5 update
936 fixed pref handling in WikiUserNew
937 added Email Notification
938 added simple Email verification
939 removed emailVerify userpref subclass: just a email property
940 changed pref binary storage layout: numarray => hash of non default values
941 print optimize message only if really done.
942 forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
943 prefs should be stored in db or homepage, besides the current session.
945 Revision 1.62 2004/03/17 18:41:05 rurban
946 initial_content and template support for CreatePage
948 Revision 1.61 2004/03/12 20:59:17 rurban
949 important cookie fix by Konstantin Zadorozhny
950 new editpage feature: JS_SEARCHREPLACE
952 Revision 1.60 2004/02/15 21:34:37 rurban
953 PageList enhanced and improved.
954 fixed new WikiAdmin... plugins
955 editpage, Theme with exp. htmlarea framework
956 (htmlarea yet committed, this is really questionable)
957 WikiUser... code with better session handling for prefs
958 enhanced UserPreferences (again)
959 RecentChanges for show_deleted: how should pages be deleted then?
961 Revision 1.59 2003/12/07 20:35:26 carstenklapp
962 Bugfix: Concurrent updates broken since after 1.3.4 release: Fatal
963 error: Call to undefined function: gettransformedcontent() in
964 /home/groups/p/ph/phpwiki/htdocs/phpwiki2/lib/editpage.php on line
967 Revision 1.58 2003/03/10 18:25:22 dairiki
968 Bug/typo fix. If you use the edit page to un/lock a page, it
969 failed with: Fatal error: Call to a member function on a
970 non-object in editpage.php on line 136
972 Revision 1.57 2003/02/26 03:40:22 dairiki
973 New action=create. Essentially the same as action=edit, except that if the
974 page already exists, it falls back to action=browse.
976 This is for use in the "question mark" links for unknown wiki words
977 to avoid problems and confusion when following links from stale pages.
978 (If the "unknown page" has been created in the interim, the user probably
979 wants to view the page before editing it.)
981 Revision 1.56 2003/02/21 18:07:14 dairiki
982 Minor, nitpicky, currently inconsequential changes.
984 Revision 1.55 2003/02/21 04:10:58 dairiki
985 Fixes for new cached markup.
986 Some minor code cleanups.
988 Revision 1.54 2003/02/16 19:47:16 dairiki
989 Update WikiDB timestamp when editing or deleting pages.
991 Revision 1.53 2003/02/15 23:20:27 dairiki
992 Redirect back to browse current version of page upon save,
993 even when no changes were made.
995 Revision 1.52 2003/01/03 22:22:00 carstenklapp
996 Minor adjustments to diff block markers ("<<<<<<<"). Source reformatting.
998 Revision 1.51 2003/01/03 02:43:26 carstenklapp
999 New class LoadFileConflictPageEditor, for merging / comparing a loaded
1000 pgsrc file with an existing page.
1007 // c-basic-offset: 4
1008 // c-hanging-comment-ender-p: nil
1009 // indent-tabs-mode: nil