2 rcs_id('$Id: editpage.php,v 1.108 2006-12-22 17:47:34 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
22 $this->meta = array('author' => $this->user->getId(),
23 'author_id' => $this->user->getAuthenticatedId(),
26 $this->tokens = array();
29 $backend = WYSIWYG_BACKEND;
30 // TODO: error message
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))
61 $page = $request->_dbi->getPage($template);
62 $current = $page->getCurrentRevision();
63 $this->_content = $current->getPackedContent();
64 } elseif ($initial_content = $request->getArg('initial_content')) {
65 $this->_content = $initial_content;
66 $this->_redirect_to = $request->getArg('save_and_redirect_to');
70 header("Content-Type: text/html; charset=" . $GLOBALS['charset']);
73 function editPage () {
76 $tokens = &$this->tokens;
77 $tokens['PAGE_LOCKED_MESSAGE'] = '';
78 $tokens['CONCURRENT_UPDATE_MESSAGE'] = '';
81 if (isset($r->args['pref']['editWidth'])
82 and ($r->getPref('editWidth') != $r->args['pref']['editWidth'])) {
83 $r->_prefs->set('editWidth', $r->args['pref']['editWidth']);
85 if (isset($r->args['pref']['editHeight'])
86 and ($r->getPref('editHeight') != $r->args['pref']['editHeight'])) {
87 $r->_prefs->set('editHeight', $r->args['pref']['editHeight']);
90 if (! $this->canEdit()) {
91 if ($this->isInitialEdit())
92 return $this->viewSource();
93 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
95 elseif ($r->getArg('save_and_redirect_to') != "") {
96 if (ENABLE_CAPTCHA && $this->Captcha->Failed()) {
97 $this->tokens['PAGE_LOCKED_MESSAGE'] =
98 HTML::p(HTML::h1($this->Captcha->failed_msg));
100 elseif ( $this->savePage()) {
102 $r->redirect(WikiURL($r->getArg('save_and_redirect_to')));
103 return true; // Page saved.
107 elseif ($this->editaction == 'save') {
108 if (ENABLE_CAPTCHA && $this->Captcha->Failed()) {
109 $this->tokens['PAGE_LOCKED_MESSAGE'] =
110 HTML::p(HTML::h1($this->Captcha->failed_msg));
112 elseif ($this->savePage()) {
113 return true; // Page saved.
120 if ($saveFailed and $this->isConcurrentUpdate())
122 // Get the text of the original page, and the two conflicting edits
123 // The diff3 class takes arrays as input. So retrieve content as
124 // an array, or convert it as necesary.
125 $orig = $this->page->getRevision($this->_currentVersion);
126 // FIXME: what if _currentVersion has be deleted?
127 $orig_content = $orig->getContent();
128 $this_content = explode("\n", $this->_content);
129 $other_content = $this->current->getContent();
130 include_once("lib/diff3.php");
131 $diff = new diff3($orig_content, $this_content, $other_content);
132 $output = $diff->merged_output(_("Your version"), _("Other version"));
133 // Set the content of the textarea to the merged diff
134 // output, and update the version
135 $this->_content = implode ("\n", $output);
136 $this->_currentVersion = $this->current->getVersion();
137 $this->version = $this->_currentVersion;
138 $unresolved = $diff->ConflictingBlocks;
139 $tokens['CONCURRENT_UPDATE_MESSAGE']
140 = $this->getConflictMessage($unresolved);
141 } elseif ($saveFailed && !$this->_isSpam) {
142 $tokens['CONCURRENT_UPDATE_MESSAGE'] =
143 HTML(HTML::h2(_("Some internal editing error")),
144 HTML::p(_("Your are probably trying to edit/create an invalid version of this page.")),
145 HTML::p(HTML::em(_("&version=-1 might help."))));
148 if ($this->editaction == 'edit_convert')
149 $tokens['PREVIEW_CONTENT'] = $this->getConvertedPreview();
150 if ($this->editaction == 'preview')
151 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
153 // FIXME: NOT_CURRENT_MESSAGE?
154 $tokens = array_merge($tokens, $this->getFormElements());
156 if (ENABLE_EDIT_TOOLBAR and !ENABLE_WYSIWYG) {
157 include_once("lib/EditToolbar.php");
158 $toolbar = new EditToolbar();
159 $tokens = array_merge($tokens, $toolbar->getTokens());
162 return $this->output('editpage', _("Edit: %s"));
165 function output ($template, $title_fs) {
167 $selected = &$this->selected;
168 $current = &$this->current;
170 if ($selected && $selected->getVersion() != $current->getVersion()) {
172 $pagelink = WikiLink($selected);
176 $pagelink = WikiLink($this->page);
179 $title = new FormattedText ($title_fs, $pagelink);
180 // not for dumphtml or viewsource
181 if (ENABLE_WYSIWYG and $template == 'editpage') {
182 $WikiTheme->addMoreHeaders($this->WysiwygEdit->Head());
183 //$tokens['PAGE_SOURCE'] = $this->WysiwygEdit->ConvertBefore($this->_content);
185 $template = Template($template, $this->tokens);
186 GeneratePage($template, $title, $rev);
191 function viewSource () {
192 assert($this->isInitialEdit());
193 assert($this->selected);
195 $this->tokens['PAGE_SOURCE'] = $this->_content;
196 $this->tokens['HIDDEN_INPUTS'] = HiddenInputs($this->request->getArgs());
197 return $this->output('viewsource', _("View Source: %s"));
200 function updateLock() {
201 if ((bool)$this->page->get('locked') == (bool)$this->locked)
202 return false; // Not changed.
204 if (!$this->user->isAdmin()) {
205 // FIXME: some sort of message
206 return false; // not allowed.
209 $this->page->set('locked', (bool)$this->locked);
210 $this->tokens['LOCK_CHANGED_MSG']
211 = $this->locked ? _("Page now locked.") : _("Page now unlocked.");
213 return true; // lock changed.
216 function savePage () {
217 $request = &$this->request;
219 if ($this->isUnchanged()) {
220 // Allow admin lock/unlock even if
221 // no text changes were made.
222 if ($this->updateLock()) {
223 $dbi = $request->getDbh();
226 // Save failed. No changes made.
227 $this->_redirectToBrowsePage();
228 // user will probably not see the rest of this...
229 include_once('lib/display.php');
230 // force browse of current version:
231 $request->setArg('version', false);
232 displayPage($request, 'nochanges');
236 if (!$this->user->isAdmin() and $this->isSpam()) {
237 $this->_isSpam = true;
240 // Save failed. No changes made.
241 $this->_redirectToBrowsePage();
242 // user will probably not see the rest of this...
243 include_once('lib/display.php');
244 // force browse of current version:
245 $request->setArg('version', false);
246 displayPage($request, 'nochanges');
251 $page = &$this->page;
253 // Include any meta-data from original page version which
254 // has not been explicitly updated.
255 // (Except don't propagate pgsrc_version --- moot for now,
256 // because at present it never gets into the db...)
257 $meta = $this->selected->getMetaData();
258 unset($meta['pgsrc_version']);
259 $meta = array_merge($meta, $this->meta);
262 $this->_content = $this->getContent();
263 $newrevision = $page->save($this->_content,
266 : $this->_currentVersion + 1,
269 if (!isa($newrevision, 'WikiDB_PageRevision')) {
270 // Save failed. (Concurrent updates).
274 // New contents successfully saved...
277 // Clean out archived versions of this page.
278 include_once('lib/ArchiveCleaner.php');
279 $cleaner = new ArchiveCleaner($GLOBALS['ExpireParams']);
280 $cleaner->cleanPageRevisions($page);
282 /* generate notification emails done in WikiDB::save to catch
283 all direct calls (admin plugins) */
285 // look at the errorstack
286 $errors = $GLOBALS['ErrorManager']->_postponed_errors;
287 $warnings = $GLOBALS['ErrorManager']->getPostponedErrorsAsHTML();
288 $GLOBALS['ErrorManager']->_postponed_errors = $errors;
290 $dbi = $request->getDbh();
294 if (empty($warnings->_content) && ! $WikiTheme->getImageURL('signature')) {
295 // Do redirect to browse page if no signature has
296 // been defined. In this case, the user will most
297 // likely not see the rest of the HTML we generate
299 $this->_redirectToBrowsePage();
302 // Force browse of current page version.
303 $request->setArg('version', false);
304 $request->setArg('action', "browse");
306 $template = Template('savepage', $this->tokens);
307 $template->replace('CONTENT', $newrevision->getTransformedContent());
308 if (!empty($warnings->_content)) {
309 $template->replace('WARNINGS', $warnings);
310 unset($GLOBALS['ErrorManager']->_postponed_errors);
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: content domain blacklist
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)
363 // Allow strictly authenticated users?
364 // TODO: mail the admin?
365 $this->tokens['PAGE_LOCKED_MESSAGE'] =
366 HTML($this->getSpamMessage(),
367 HTML::p(HTML::strong(_("Too many external links."))));
370 // 2. external babycart (SpamAssassin) check
371 // This will probably prevent from discussing sex or viagra related topics. So beware.
372 if (ENABLE_SPAMASSASSIN) {
373 include_once("lib/spam_babycart.php");
374 if ($babycart = check_babycart($newtext, $request->get("REMOTE_ADDR"),
375 $this->user->getId())) {
376 // TODO: mail the admin
377 if (is_array($babycart))
378 $this->tokens['PAGE_LOCKED_MESSAGE'] =
379 HTML($this->getSpamMessage(),
380 HTML::p(HTML::em(_("SpamAssassin reports: "),
381 join("\n", $babycart))));
385 // 3. extract (new) links and check surbl for blocked domains
386 if (ENABLE_SPAMBLOCKLIST and $this->numLinks($newtext)) {
387 include_once("lib/SpamBlocklist.php");
388 include_once("lib/InlineParser.php");
389 $parsed = TransformLinks($newtext);
390 foreach ($parsed->_content as $link) {
391 if (isa($link, 'Cached_ExternalLink')) {
392 $uri = $link->_getURL($this->page->getName());
393 if ($res = IsBlackListed($uri)) {
394 // TODO: mail the admin
395 $this->tokens['PAGE_LOCKED_MESSAGE'] =
396 HTML($this->getSpamMessage(),
397 HTML::p(HTML::strong(_("External links contain blocked domains:")),
398 HTML::ul(HTML::li(sprintf(_("%s is listed at %s"),
399 $res[2], $res[0])))));
409 /** Number of external links in the wikitext
411 function numLinks(&$text) {
412 return substr_count($text, "http://") + substr_count($text, "https://");
415 /** Header of the Anti Spam message
417 function getSpamMessage () {
419 HTML(HTML::h2(_("Spam Prevention")),
420 HTML::p(_("This page edit seems to contain spam and was therefore not saved."),
422 _("Sorry for the inconvenience.")),
426 function getPreview () {
427 include_once('lib/PageType.php');
428 $this->_content = $this->getContent();
429 return new TransformedText($this->page, $this->_content, $this->meta);
432 function getConvertedPreview () {
433 include_once('lib/PageType.php');
434 $this->_content = $this->getContent();
435 $this->meta['markup'] = 2.0;
436 $this->_content = ConvertOldMarkup($this->_content);
437 return new TransformedText($this->page, $this->_content, $this->meta);
440 // possibly convert HTMLAREA content back to Wiki markup
441 function getContent () {
442 if (ENABLE_WYSIWYG) {
443 // don't store everything as html
444 if (!WYSIWYG_DEFAULT_PAGETYPE_HTML) {
445 // Wikiwyg shortcut to avoid the InlineTransformer:
446 if (WYSIWYG_BACKEND == "Wikiwyg") return $this->_content;
447 $xml_output = $this->WysiwygEdit->ConvertAfter($this->_content);
448 $this->_content = join("", $xml_output->_content);
450 $this->meta['pagetype'] = 'html';
452 return $this->_content;
454 return $this->_content;
458 function getLockedMessage () {
460 HTML(HTML::h2(_("Page Locked")),
461 HTML::p(_("This page has been locked by the administrator so your changes can not be saved.")),
462 HTML::p(_("(Copy your changes to the clipboard. You can try editing a different page or save your text in a text editor.)")),
463 HTML::p(_("Sorry for the inconvenience.")));
466 function getConflictMessage ($unresolved = false) {
468 xgettext only knows about c/c++ line-continuation strings
469 it does not know about php's dot operator.
470 We want to translate this entire paragraph as one string, of course.
473 //$re_edit_link = Button('edit', _("Edit the new version"), $this->page);
476 $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.",
477 "<<<<<<< ". _("Your version"),
478 ">>>>>>> ". _("Other version")));
480 $message = HTML::p(_("Please check it through before saving."));
484 /*$steps = HTML::ol(HTML::li(_("Copy your changes to the clipboard or to another temporary place (e.g. text editor).")),
485 HTML::li(fmt("%s of the page. You should now see the most current version of the page. Your changes are no longer there.",
487 HTML::li(_("Make changes to the file again. Paste your additions from the clipboard (or text editor).")),
488 HTML::li(_("Save your updated changes.")));
491 HTML(HTML::h2(_("Conflicting Edits!")),
492 HTML::p(_("In the time since you started editing this page, another user has saved a new version of it.")),
493 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.")),
498 function getTextArea () {
499 $request = &$this->request;
501 $readonly = ! $this->canEdit(); // || $this->isConcurrentUpdate();
503 // WYSIWYG will need two pagetypes: raw wikitest and converted html
504 if (ENABLE_WYSIWYG) {
505 $this->_wikicontent = $this->_content;
506 $this->_content = $this->WysiwygEdit->ConvertBefore($this->_content);
507 // $this->getPreview();
508 //$this->_htmlcontent = $this->_content->asXML();
511 $textarea = HTML::textarea(array('class'=> 'wikiedit',
512 'name' => 'edit[content]',
513 'id' => 'edit:content',
514 'rows' => $request->getPref('editHeight'),
515 'cols' => $request->getPref('editWidth'),
516 'readonly' => (bool) $readonly),
518 /** <textarea wrap="virtual"> is not valid XHTML but Netscape 4 requires it
519 * to wrap long lines.
522 $textarea->setAttr('wrap', 'virtual');
523 if (ENABLE_WYSIWYG) {
524 return $this->WysiwygEdit->Textarea($textarea, $this->_wikicontent,
525 $textarea->getAttr('name'));
530 function getFormElements () {
532 $request = &$this->request;
533 $page = &$this->page;
535 $h = array('action' => 'edit',
536 'pagename' => $page->getName(),
537 'version' => $this->version,
538 'edit[pagetype]' => $this->meta['pagetype'],
539 'edit[current_version]' => $this->_currentVersion);
541 $el['HIDDEN_INPUTS'] = HiddenInputs($h);
542 $el['EDIT_TEXTAREA'] = $this->getTextArea();
543 if ( ENABLE_CAPTCHA ) {
544 $el = array_merge($el, $this->Captcha->getFormElements());
547 = HTML::input(array('type' => 'text',
548 'class' => 'wikitext',
549 'id' => 'edit:summary',
550 'name' => 'edit[summary]',
553 'value' => $this->meta['summary']));
555 = HTML::input(array('type' => 'checkbox',
556 'name' => 'edit[minor_edit]',
557 'id' => 'edit:minor_edit',
558 'checked' => (bool) $this->meta['is_minor_edit']));
560 = HTML::input(array('type' => 'checkbox',
561 'name' => 'edit[markup]',
563 'checked' => $this->meta['markup'] < 2.0,
564 'id' => 'useOldMarkup',
565 'onclick' => 'showOldMarkupRules(this.checked)'));
566 $el['OLD_MARKUP_CONVERT'] = ($this->meta['markup'] < 2.0)
567 ? Button('submit:edit[edit_convert]', _("Convert"), 'wikiaction') : '';
569 = HTML::input(array('type' => 'checkbox',
570 'name' => 'edit[locked]',
571 'id' => 'edit:locked',
572 'disabled' => (bool) !$this->user->isadmin(),
573 'checked' => (bool) $this->locked));
575 $el['PREVIEW_B'] = Button('submit:edit[preview]', _("Preview"),
577 array('accesskey'=> 'p'));
579 //if (!$this->isConcurrentUpdate() && $this->canEdit())
580 $el['SAVE_B'] = Button('submit:edit[save]',
581 _("Save"), 'wikiaction',
582 array('accesskey'=> 's'));
583 $el['IS_CURRENT'] = $this->version == $this->current->getVersion();
586 = HTML::input(array('type' => 'text',
589 'class' => "numeric",
590 'name' => 'pref[editWidth]',
591 'id' => 'pref:editWidth',
592 'value' => $request->getPref('editWidth'),
593 'onchange' => 'this.form.submit();'));
595 = HTML::input(array('type' => 'text',
598 'class' => "numeric",
599 'name' => 'pref[editHeight]',
600 'id' => 'pref:editHeight',
601 'value' => $request->getPref('editHeight'),
602 'onchange' => 'this.form.submit();'));
603 $el['SEP'] = $WikiTheme->getButtonSeparator();
604 $el['AUTHOR_MESSAGE'] = fmt("Author will be logged as %s.",
605 HTML::em($this->user->getId()));
610 function _redirectToBrowsePage() {
611 $this->request->redirect(WikiURL($this->page, false, 'absolute_url'));
614 function _restoreState () {
615 $request = &$this->request;
617 $posted = $request->getArg('edit');
618 $request->setArg('edit', false);
620 if (!$posted || !$request->isPost()
621 || $request->getArg('action') != 'edit')
624 if (!isset($posted['content']) || !is_string($posted['content']))
626 $this->_content = preg_replace('/[ \t\r]+\n/', "\n",
627 rtrim($posted['content']));
628 $this->_content = $this->getContent();
630 $this->_currentVersion = (int) $posted['current_version'];
632 if ($this->_currentVersion < 0)
634 if ($this->_currentVersion > $this->current->getVersion())
635 return false; // FIXME: some kind of warning?
637 $is_old_markup = !empty($posted['markup']) && $posted['markup'] == 'old';
638 $meta['markup'] = $is_old_markup ? false : 2.0;
639 $meta['summary'] = trim(substr($posted['summary'], 0, 256));
640 $meta['is_minor_edit'] = !empty($posted['minor_edit']);
641 $meta['pagetype'] = !empty($posted['pagetype']) ? $posted['pagetype'] : false;
642 if ( ENABLE_CAPTCHA )
643 $meta['captcha_input'] = !empty($posted['captcha_input']) ?
644 $posted['captcha_input'] : '';
646 $this->meta = array_merge($this->meta, $meta);
647 $this->locked = !empty($posted['locked']);
649 if (!empty($posted['preview']))
650 $this->editaction = 'preview';
651 elseif (!empty($posted['save']))
652 $this->editaction = 'save';
653 elseif (!empty($posted['edit_convert']))
654 $this->editaction = 'edit_convert';
656 $this->editaction = 'edit';
661 function _initializeState () {
662 $request = &$this->request;
663 $current = &$this->current;
664 $selected = &$this->selected;
665 $user = &$this->user;
668 NoSuchRevision($request, $this->page, $this->version); // noreturn
670 $this->_currentVersion = $current->getVersion();
671 $this->_content = $selected->getPackedContent();
673 $this->locked = $this->page->get('locked');
675 // If author same as previous author, default minor_edit to on.
676 $age = $this->meta['mtime'] - $current->get('mtime');
677 $this->meta['is_minor_edit'] = ( $age < MINOR_EDIT_TIMEOUT
678 && $current->get('author') == $user->getId()
681 // Default for new pages is new-style markup.
682 if ($selected->hasDefaultContents())
683 $is_new_markup = true;
685 $is_new_markup = $selected->get('markup') >= 2.0;
687 $this->meta['markup'] = $is_new_markup ? 2.0: false;
688 $this->meta['pagetype'] = $selected->get('pagetype');
689 if ($this->meta['pagetype'] == 'wikiblog')
690 $this->meta['summary'] = $selected->get('summary'); // keep blog title
692 $this->meta['summary'] = '';
693 $this->editaction = 'edit';
697 class LoadFileConflictPageEditor
700 function editPage ($saveFailed = true) {
701 $tokens = &$this->tokens;
703 if (!$this->canEdit()) {
704 if ($this->isInitialEdit()) {
705 return $this->viewSource();
707 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
709 elseif ($this->editaction == 'save') {
710 if ($this->savePage()) {
711 return true; // Page saved.
716 if ($saveFailed || $this->isConcurrentUpdate())
718 // Get the text of the original page, and the two conflicting edits
719 // The diff class takes arrays as input. So retrieve content as
720 // an array, or convert it as necesary.
721 $orig = $this->page->getRevision($this->_currentVersion);
722 $this_content = explode("\n", $this->_content);
723 $other_content = $this->current->getContent();
724 include_once("lib/diff.php");
725 $diff2 = new Diff($other_content, $this_content);
726 $context_lines = max(4, count($other_content) + 1,
727 count($this_content) + 1);
728 $fmt = new BlockDiffFormatter($context_lines);
730 $this->_content = $fmt->format($diff2);
731 // FIXME: integrate this into class BlockDiffFormatter
732 $this->_content = str_replace(">>>>>>>\n<<<<<<<\n", "=======\n",
734 $this->_content = str_replace("<<<<<<<\n>>>>>>>\n", "=======\n",
737 $this->_currentVersion = $this->current->getVersion();
738 $this->version = $this->_currentVersion;
739 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage();
742 if ($this->editaction == 'edit_convert')
743 $tokens['PREVIEW_CONTENT'] = $this->getConvertedPreview();
744 if ($this->editaction == 'preview')
745 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
747 // FIXME: NOT_CURRENT_MESSAGE?
748 $tokens = array_merge($tokens, $this->getFormElements());
750 return $this->output('editpage', _("Merge and Edit: %s"));
751 // FIXME: this doesn't display
754 function output ($template, $title_fs) {
755 $selected = &$this->selected;
756 $current = &$this->current;
758 if ($selected && $selected->getVersion() != $current->getVersion()) {
760 $pagelink = WikiLink($selected);
764 $pagelink = WikiLink($this->page);
767 //$title = new FormattedText ($title_fs, $pagelink);
768 $template = Template($template, $this->tokens);
770 //GeneratePage($template, $title, $rev);
775 function getConflictMessage () {
776 $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.",
779 HTML::p(_("Please check it through before saving."))));
785 $Log: not supported by cvs2svn $
786 Revision 1.107 2006/05/13 19:59:54 rurban
787 added wysiwyg_editor-1.3a feature by Jean-Nicolas GEREONE <jean-nicolas.gereone@st.com>
788 converted wysiwyg_editor-1.3a js to WysiwygEdit framework
789 changed default ENABLE_WYSIWYG = true and added WYSIWYG_BACKEND = Wikiwyg
791 Revision 1.106 2005/11/21 22:03:08 rurban
792 fix syntax error inside ENABLE_SPAMBLOCKLIST
794 Revision 1.105 2005/11/21 20:53:59 rurban
795 beautify request pref lines, no antispam if admin (netznetz request), user is a member anyway
797 Revision 1.104 2005/10/31 17:20:40 rurban
800 Revision 1.103 2005/10/31 17:09:13 rurban
801 use better constant WYSIWYG_DEFAULT_PAGETYPE_HTML
803 Revision 1.102 2005/10/31 16:47:14 rurban
804 enable wysiwyg html converters
806 Revision 1.101 2005/10/30 16:12:28 rurban
807 simplify viewsource tokens
809 Revision 1.100 2005/10/30 14:20:42 rurban
810 move Captcha specific vars and methods into a Captcha object
811 randomize Captcha chars positions and angles (smoothly)
813 Revision 1.99 2005/10/29 08:21:58 rurban
814 ENABLE_SPAMBLOCKLIST:
815 Check for links to blocked external tld domains in new edits, against
816 multi.surbl.org and bl.spamcop.net.
818 Revision 1.98 2005/10/10 19:37:04 rurban
819 change USE_HTMLAREA to ENABLE WYSIWYG, add NUM_SPAM_LINKS=20
821 Revision 1.97 2005/09/26 06:32:22 rurban
822 [] is forbidden in id tags. Renamed to use :
824 Revision 1.96 2005/05/06 17:54:22 rurban
825 silence Preview warnings for PAGE_LOCKED_MESSAGE, CONCURRENT_UPDATE_MESSAGE (thanks to schorni)
827 Revision 1.95 2005/04/25 20:17:14 rurban
828 captcha feature by Benjamin Drieu. Patch #1110699
830 Revision 1.94 2005/02/28 20:23:31 rurban
833 Revision 1.93 2005/02/27 19:31:52 rurban
834 hack: display errorstack without sideeffects (save and restore)
836 Revision 1.92 2005/01/29 20:37:21 rurban
837 no edit toolbar at all if ENABLE_EDITTOOLBAR = false
839 Revision 1.91 2005/01/25 07:05:49 rurban
840 extract toolbar code, support new tags to get rid of php inside templates
842 Revision 1.90 2005/01/22 12:46:15 rurban
843 fix oldmakrup button label
844 update pref[edit*] settings
846 Revision 1.89 2005/01/21 14:07:49 rurban
849 Revision 1.88 2004/12/17 16:39:03 rurban
852 Revision 1.87 2004/12/16 18:28:05 rurban
853 keep wikiblog summary = page title
855 Revision 1.86 2004/12/11 14:50:15 rurban
856 new edit_convert button, to get rid of old markup eventually
858 Revision 1.85 2004/12/06 19:49:56 rurban
859 enable action=remove which is undoable and seeable in RecentChanges: ADODB ony for now.
860 renamed delete_page to purge_page.
861 enable action=edit&version=-1 to force creation of a new version.
862 added BABYCART_PATH config
863 fixed magiqc in adodb.inc.php
866 Revision 1.84 2004/12/04 12:58:26 rurban
867 enable babycart Blog::SpamAssassin module on ENABLE_SPAMASSASSIN=true
868 (currently only for php >= 4.3.0)
870 Revision 1.83 2004/12/04 11:55:39 rurban
871 First simple AntiSpam prevention:
872 No more than 20 new http:// links allowed
874 Revision 1.82 2004/11/30 22:21:56 rurban
875 changed gif to optimized (pngout) png
877 Revision 1.81 2004/11/29 17:57:27 rurban
878 translated pulldown buttons
880 Revision 1.80 2004/11/25 17:20:51 rurban
881 and again a couple of more native db args: backlinks
883 Revision 1.79 2004/11/21 11:59:20 rurban
884 remove final \n to be ob_cache independent
886 Revision 1.78 2004/11/16 17:57:45 rurban
887 fix search&replace button
888 use new addTagButton machinery
889 new showPulldown for categories, TODO: in a seperate request
891 Revision 1.77 2004/11/15 15:52:35 rurban
894 Revision 1.76 2004/11/15 15:37:34 rurban
896 don't use document.write for replace, otherwise self.opener is not defined.
898 Revision 1.75 2004/09/16 08:00:52 rurban
901 Revision 1.74 2004/07/03 07:36:28 rurban
902 do not get unneccessary content
904 Revision 1.73 2004/06/16 21:23:44 rurban
905 fixed non-object fatal #215
907 Revision 1.72 2004/06/14 11:31:37 rurban
908 renamed global $Theme to $WikiTheme (gforge nameclash)
909 inherit PageList default options from PageList
910 default sortby=pagename
911 use options in PageList_Selectable (limit, sortby, ...)
912 added action revert, with button at action=diff
913 added option regex to WikiAdminSearchReplace
915 Revision 1.71 2004/06/03 18:06:29 rurban
916 fix file locking issues (only needed on write)
917 fixed immediate LANG and THEME in-session updates if not stored in prefs
918 advanced editpage toolbars (search & replace broken)
920 Revision 1.70 2004/06/02 20:47:47 rurban
921 dont use the wikiaction class
923 Revision 1.69 2004/06/02 10:17:56 rurban
924 integrated search/replace into toolbar
925 added save+preview buttons
927 Revision 1.68 2004/06/01 15:28:00 rurban
928 AdminUser only ADMIN_USER not member of Administrators
929 some RateIt improvements by dfrankow
932 Revision _1.6 2004/05/26 15:48:00 syilek
933 fixed problem with creating page with slashes from one true page
935 Revision _1.5 2004/05/25 16:51:53 syilek
936 added ability to create a page from the category page and not have to edit it
938 Revision 1.67 2004/05/27 17:49:06 rurban
939 renamed DB_Session to DbSession (in CVS also)
940 added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
941 remove leading slash in error message
942 added force_unlock parameter to File_Passwd (no return on stale locks)
943 fixed adodb session AffectedRows
944 added FileFinder helpers to unify local filenames and DATA_PATH names
945 editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
947 Revision 1.66 2004/04/29 23:25:12 rurban
948 re-ordered locale init (as in 1.3.9)
949 fixed loadfile with subpages, and merge/restore anyway
952 Revision 1.65 2004/04/18 01:11:52 rurban
953 more numeric pagename fixes.
954 fixed action=upload with merge conflict warnings.
955 charset changed from constant to global (dynamic utf-8 switching)
957 Revision 1.64 2004/04/06 19:48:56 rurban
958 temp workaround for action=edit AddComment form
960 Revision 1.63 2004/03/24 19:39:02 rurban
961 php5 workaround code (plus some interim debugging code in XmlElement)
962 php5 doesn't work yet with the current XmlElement class constructors,
963 WikiUserNew does work better than php4.
964 rewrote WikiUserNew user upgrading to ease php5 update
965 fixed pref handling in WikiUserNew
966 added Email Notification
967 added simple Email verification
968 removed emailVerify userpref subclass: just a email property
969 changed pref binary storage layout: numarray => hash of non default values
970 print optimize message only if really done.
971 forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
972 prefs should be stored in db or homepage, besides the current session.
974 Revision 1.62 2004/03/17 18:41:05 rurban
975 initial_content and template support for CreatePage
977 Revision 1.61 2004/03/12 20:59:17 rurban
978 important cookie fix by Konstantin Zadorozhny
979 new editpage feature: JS_SEARCHREPLACE
981 Revision 1.60 2004/02/15 21:34:37 rurban
982 PageList enhanced and improved.
983 fixed new WikiAdmin... plugins
984 editpage, Theme with exp. htmlarea framework
985 (htmlarea yet committed, this is really questionable)
986 WikiUser... code with better session handling for prefs
987 enhanced UserPreferences (again)
988 RecentChanges for show_deleted: how should pages be deleted then?
990 Revision 1.59 2003/12/07 20:35:26 carstenklapp
991 Bugfix: Concurrent updates broken since after 1.3.4 release: Fatal
992 error: Call to undefined function: gettransformedcontent() in
993 /home/groups/p/ph/phpwiki/htdocs/phpwiki2/lib/editpage.php on line
996 Revision 1.58 2003/03/10 18:25:22 dairiki
997 Bug/typo fix. If you use the edit page to un/lock a page, it
998 failed with: Fatal error: Call to a member function on a
999 non-object in editpage.php on line 136
1001 Revision 1.57 2003/02/26 03:40:22 dairiki
1002 New action=create. Essentially the same as action=edit, except that if the
1003 page already exists, it falls back to action=browse.
1005 This is for use in the "question mark" links for unknown wiki words
1006 to avoid problems and confusion when following links from stale pages.
1007 (If the "unknown page" has been created in the interim, the user probably
1008 wants to view the page before editing it.)
1010 Revision 1.56 2003/02/21 18:07:14 dairiki
1011 Minor, nitpicky, currently inconsequential changes.
1013 Revision 1.55 2003/02/21 04:10:58 dairiki
1014 Fixes for new cached markup.
1015 Some minor code cleanups.
1017 Revision 1.54 2003/02/16 19:47:16 dairiki
1018 Update WikiDB timestamp when editing or deleting pages.
1020 Revision 1.53 2003/02/15 23:20:27 dairiki
1021 Redirect back to browse current version of page upon save,
1022 even when no changes were made.
1024 Revision 1.52 2003/01/03 22:22:00 carstenklapp
1025 Minor adjustments to diff block markers ("<<<<<<<"). Source reformatting.
1027 Revision 1.51 2003/01/03 02:43:26 carstenklapp
1028 New class LoadFileConflictPageEditor, for merging / comparing a loaded
1029 pgsrc file with an existing page.
1036 // c-basic-offset: 4
1037 // c-hanging-comment-ender-p: nil
1038 // indent-tabs-mode: nil