2 rcs_id('$Id: editpage.php,v 1.68 2004-06-01 15:28:00 rurban Exp $');
4 require_once('lib/Template.php');
6 // USE_HTMLAREA - WYSIWYG HTML Editor
7 // Not yet enabled, since we cannot convert HTML to Wiki Markup yet.
8 // (See HtmlParser.php for the ongoing efforts)
9 // We might use a HTML PageType, which is contra wiki, but some people might prefer HTML markup.
10 // TODO: Change from constant to user preference variable (checkbox setting),
11 // when HtmlParser is finished.
12 if (!defined('USE_HTMLAREA')) define('USE_HTMLAREA',false);
13 if (USE_HTMLAREA) require_once('lib/htmlarea.php');
17 function PageEditor (&$request) {
18 $this->request = &$request;
20 $this->user = $request->getUser();
21 $this->page = $request->getPage();
23 $this->current = $this->page->getCurrentRevision();
25 // HACKish short circuit to browse on action=create
26 if ($request->getArg('action') == 'create') {
27 if (! $this->current->hasDefaultContents())
28 $request->redirect(WikiURL($this->page->getName())); // noreturn
32 $this->meta = array('author' => $this->user->getId(),
33 'author_id' => $this->user->getAuthenticatedId(),
36 $this->tokens = array();
38 $version = $request->getArg('version');
39 if ($version !== false) {
40 $this->selected = $this->page->getRevision($version);
41 $this->version = $version;
44 $this->selected = $this->current;
45 $this->version = $this->current->getVersion();
48 if ($this->_restoreState()) {
49 $this->_initialEdit = false;
52 $this->_initializeState();
53 $this->_initialEdit = true;
55 // The edit request has specified some initial content from a template
56 if ( ($template = $request->getArg('template')) and
57 $request->_dbi->isWikiPage($template)) {
58 $page = $request->_dbi->getPage($template);
59 $current = $page->getCurrentRevision();
60 $this->_content = $current->getPackedContent();
61 } elseif ($initial_content = $request->getArg('initial_content')) {
62 $this->_content = $initial_content;
63 $this->_redirect_to = $request->getArg('save_and_redirect_to');
67 header("Content-Type: text/html; charset=" . $GLOBALS['charset']);
70 function editPage () {
72 $tokens = &$this->tokens;
74 if (! $this->canEdit()) {
75 if ($this->isInitialEdit())
76 return $this->viewSource();
77 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
79 elseif ($this->request->getArg('save_and_redirect_to') != "") {
80 if ($this->savePage()) {
82 $this->request->redirect(WikiURL($this->request->getArg('save_and_redirect_to')));
83 return true; // Page saved.
87 elseif ($this->editaction == 'save') {
88 if ($this->savePage()) {
89 return true; // Page saved.
94 if ($saveFailed || $this->isConcurrentUpdate())
96 // Get the text of the original page, and the two conflicting edits
97 // The diff3 class takes arrays as input. So retrieve content as
98 // an array, or convert it as necesary.
99 $orig = $this->page->getRevision($this->_currentVersion);
100 // FIXME: what if _currentVersion has be deleted?
101 $orig_content = $orig->getContent();
102 $this_content = explode("\n", $this->_content);
103 $other_content = $this->current->getContent();
104 include_once("lib/diff3.php");
105 $diff = new diff3($orig_content, $this_content, $other_content);
106 $output = $diff->merged_output(_("Your version"), _("Other version"));
107 // Set the content of the textarea to the merged diff
108 // output, and update the version
109 $this->_content = implode ("\n", $output);
110 $this->_currentVersion = $this->current->getVersion();
111 $this->version = $this->_currentVersion;
112 $unresolved = $diff->ConflictingBlocks;
113 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage($unresolved);
116 if ($this->editaction == 'preview')
117 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
119 // FIXME: NOT_CURRENT_MESSAGE?
121 $tokens = array_merge($tokens, $this->getFormElements());
123 // TODO: add this to the EDIT_TOOLBAR
124 if (defined('JS_SEARCHREPLACE') and JS_SEARCHREPLACE) {
125 $tokens['JS_SEARCHREPLACE'] = 1;
126 $GLOBALS['Theme']->addMoreHeaders(Javascript("
127 var wart=0, d, f, x='', replacewin, pretxt=new Array(), pretxt_anzahl=0;
128 var fag='<font face=\"arial,helvetica,sans-serif\" size=\"-1\">', fr='<font color=\"#cc0000\">', spn='<span class=\"grey\">';
130 function define_f() {
131 f=document.getElementById('editpage');
132 f.editarea=document.getElementById('edit[content]');
133 if(f.rck.style) f.rck.style.color='#ececec';
138 replacewin=window.open('','','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,height=90,width=450');
139 replacewin.window.document.write('<html><head><title>"._("Search & Replace")."</title><style type=\"text/css\"><'+'!'+'-- input.btt {font-family:Tahoma,Verdana,Geneva,sans-serif;font-size:10pt} --'+'></style></head><body bgcolor=\"#dddddd\" onload=\"if(document.forms[0].ein.focus) document.forms[0].ein.focus()\"><form><center><table><tr><td align=\"right\">'+fag+'"._("Search").":</font></td><td align=\"left\"><input type=\"text\" name=\"ein\" size=\"50\" maxlength=\"500\"></td></tr><tr><td align=\"right\">'+fag+' "._("Replace with").":</font></td><td align=\"left\"><input type=\"text\" name=\"aus\" size=\"50\" maxlength=\"500\"></td></tr><tr><td colspan=\"2\" align=\"center\"><input class=\"btt\" type=\"button\" value=\" "._("OK")." \" onclick=\"self.opener.do_replace()\"> <input class=\"btt\" type=\"button\" value=\""._("Close")."\" onclick=\"self.close()\"></td></tr></table></center></form></body></html>');
140 replacewin.window.document.close();
143 function do_replace() {
144 var txt=pretxt[pretxt_anzahl]=f.editarea.value, ein=new RegExp(replacewin.document.forms[0].ein.value,'g'), aus=replacewin.document.forms[0].aus.value;
145 if(ein==''||ein==null) {
146 replacewin.window.document.forms[0].ein.focus();
149 var z_repl=txt.match(ein)? txt.match(ein).length : 0;
150 txt=txt.replace(ein,aus);
151 ein=ein.toString().substring(1,ein.toString().length-2);
152 result(z_repl, 'Substring \"'+ein+'\" found '+z_repl+' times. Replace with \"'+aus+'\"?', txt, 'String \"'+ein+'\" not found.');
153 replacewin.window.focus();
154 replacewin.window.document.forms[0].ein.focus();
156 function result(zahl,frage,txt,alert_txt) {
157 if(wart!=0&&wart.window) {
162 if(window.confirm(frage)==true) {
163 f.editarea.value=txt;
165 if(f.rck.style) f.rck.style.color='#000000';
166 f.rck.value='"._("Undo")."';
168 } else alert(alert_txt);
171 if(pretxt_anzahl==0) return;
172 else if(pretxt_anzahl>0) {
173 f.editarea.value=pretxt[pretxt_anzahl-1];
174 pretxt[pretxt_anzahl]=null;
176 if(pretxt_anzahl==0) {
177 alert('Operation undone.');
178 if(f.rck.style) f.rck.style.color='#ececec';
179 f.rck.value='("._("Undo").")';
180 if(f.rck.blur) f.rck.blur();
185 pretxt[pretxt_anzahl]=f.editarea.value;
187 if(f.rck.style) f.rck.style.color='#000000';
188 f.rck.value='"._("Undo")."';
191 $GLOBALS['Theme']->addMoreAttr('body'," onload='define_f()'");
193 $GLOBALS['Theme']->addMoreAttr('body',"document.getElementById('edit[content]').editarea.focus()");
195 if (defined('ENABLE_EDIT_TOOLBAR') and ENABLE_EDIT_TOOLBAR) {
196 $GLOBALS['Theme']->addMoreHeaders(JavaScript('',array('src'=>$GLOBALS['Theme']->_findData("toolbar.js"))));
197 $tokens['EDIT_TOOLBAR'] = $this->toolbar();
199 $tokens['EDIT_TOOLBAR'] = '';
202 return $this->output('editpage', _("Edit: %s"));
205 function toolbar () {
209 "image"=>"ed_format_bold.gif",
212 "sample"=>_("Bold text"),
213 "tip"=>_("Bold text")),
214 array("image"=>"ed_format_italic.gif",
217 "sample"=>_("Italic text"),
218 "tip"=>_("Italic text")),
219 array("image"=>"ed_pagelink.gif",
222 "sample"=>_("[ Label | PageName]"),
223 "tip"=>_("Link to page")),
224 array("image"=>"ed_link.gif",
227 "sample"=>_("[label | http://www.example.com]"),
228 "tip"=>_("External link (remember http:// prefix)")),
229 array("image"=>"ed_headline.gif",
232 "sample"=>_("Headline text"),
233 "tip"=>_("Level 1 headline")),
234 array("image"=>"ed_image.gif",
237 "sample"=>_("Example.jpg"),
238 "tip"=>_("Embedded image")),
239 array("image"=>"ed_nowiki.gif",
240 "open"=>"\\n\\<verbatim\\>\\n",
241 "close"=>"\\n\\</verbatim\\>\\n",
242 "sample"=>_("Insert non-formatted text here"),
243 "tip"=>_("Ignore wiki formatting")),
244 array("image"=>"ed_sig.gif",
245 "open" => "--" . $GLOBALS['request']->_user->UserName(),
248 "tip"=>_("Your signature")),
249 array("image"=>"ed_hr.gif",
250 "open"=>"\\n----\\n",
253 "tip"=>_("Horizontal line"))
255 $toolbar = "document.writeln(\"<div class=\\\"edit-toolbar\\\" id=\\\"toolbar\\\">\");\n";
256 foreach ($toolarray as $tool) {
257 $image = $Theme->getImageURL($tool["image"]);
258 $open = $tool["open"];
259 $close = $tool["close"];
260 $sample = addslashes( $tool["sample"] );
261 // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
262 // Older browsers show a "speedtip" type message only for ALT.
263 // Ideally these should be different, realistically they
264 // probably don't need to be.
265 $tip = addslashes( $tool["tip"] );
266 $toolbar.="addButton('$image','$tip','$open','$close','$sample');\n";
268 $toolbar.="addInfobox('" . addslashes( _( "infobox" ) ) . "');\n";
269 $toolbar.="document.writeln(\"</div>\");";
270 return Javascript($toolbar);
273 function output ($template, $title_fs) {
275 $selected = &$this->selected;
276 $current = &$this->current;
278 if ($selected && $selected->getVersion() != $current->getVersion()) {
280 $pagelink = WikiLink($selected);
284 $pagelink = WikiLink($this->page);
288 $title = new FormattedText ($title_fs, $pagelink);
289 if ($template == 'editpage' and USE_HTMLAREA) {
290 $Theme->addMoreHeaders(Edit_HtmlArea_Head());
291 //$tokens['PAGE_SOURCE'] = Edit_HtmlArea_ConvertBefore($this->_content);
293 $template = Template($template, $this->tokens);
294 GeneratePage($template, $title, $rev);
299 function viewSource () {
300 assert($this->isInitialEdit());
301 assert($this->selected);
303 $this->tokens['PAGE_SOURCE'] = $this->_content;
304 return $this->output('viewsource', _("View Source: %s"));
307 function updateLock() {
308 if ((bool)$this->page->get('locked') == (bool)$this->locked)
309 return false; // Not changed.
311 if (!$this->user->isAdmin()) {
312 // FIXME: some sort of message
313 return false; // not allowed.
316 $this->page->set('locked', (bool)$this->locked);
317 $this->tokens['LOCK_CHANGED_MSG']
318 = $this->locked ? _("Page now locked.") : _("Page now unlocked.");
320 return true; // lock changed.
323 function savePage () {
324 $request = &$this->request;
326 if ($this->isUnchanged()) {
327 // Allow admin lock/unlock even if
328 // no text changes were made.
329 if ($this->updateLock()) {
330 $dbi = $request->getDbh();
333 // Save failed. No changes made.
334 $this->_redirectToBrowsePage();
335 // user will probably not see the rest of this...
336 include_once('lib/display.php');
337 // force browse of current version:
338 $request->setArg('version', false);
339 displayPage($request, 'nochanges');
343 $page = &$this->page;
345 // Include any meta-data from original page version which
346 // has not been explicitly updated.
347 // (Except don't propagate pgsrc_version --- moot for now,
348 // because at present it never gets into the db...)
349 $meta = $this->selected->getMetaData();
350 unset($meta['pgsrc_version']);
351 $meta = array_merge($meta, $this->meta);
354 $this->_content = $this->getContent();
355 $newrevision = $page->save($this->_content, $this->_currentVersion + 1, $meta);
356 if (!isa($newrevision, 'wikidb_pagerevision')) {
357 // Save failed. (Concurrent updates).
361 // New contents successfully saved...
364 // Clean out archived versions of this page.
365 include_once('lib/ArchiveCleaner.php');
366 $cleaner = new ArchiveCleaner($GLOBALS['ExpireParams']);
367 $cleaner->cleanPageRevisions($page);
369 /* generate notification emails done in WikiDB::save to catch all direct calls
372 $dbi = $request->getDbh();
373 $warnings = $dbi->GenericWarnings();
377 if (empty($warnings) && ! $Theme->getImageURL('signature')) {
378 // Do redirect to browse page if no signature has
379 // been defined. In this case, the user will most
380 // likely not see the rest of the HTML we generate
382 $this->_redirectToBrowsePage();
385 // Force browse of current page version.
386 $request->setArg('version', false);
387 //$request->setArg('action', false);
389 $template = Template('savepage', $this->tokens);
390 $template->replace('CONTENT', $newrevision->getTransformedContent());
391 if (!empty($warnings))
392 $template->replace('WARNINGS', $warnings);
394 $pagelink = WikiLink($page);
396 GeneratePage($template, fmt("Saved: %s", $pagelink), $newrevision);
400 function isConcurrentUpdate () {
401 assert($this->current->getVersion() >= $this->_currentVersion);
402 return $this->current->getVersion() != $this->_currentVersion;
405 function canEdit () {
406 return !$this->page->get('locked') || $this->user->isAdmin();
409 function isInitialEdit () {
410 return $this->_initialEdit;
413 function isUnchanged () {
414 $current = &$this->current;
416 if ($this->meta['markup'] != $current->get('markup'))
419 return $this->_content == $current->getPackedContent();
422 function getPreview () {
423 include_once('lib/PageType.php');
424 $this->_content = $this->getContent();
425 return new TransformedText($this->page, $this->_content, $this->meta);
428 // possibly convert HTMLAREA content back to Wiki markup
429 function getContent () {
431 $xml_output = Edit_HtmlArea_ConvertAfter($this->_content);
432 $this->_content = join("",$xml_output->_content);
433 return $this->_content;
435 return $this->_content;
439 function getLockedMessage () {
441 HTML(HTML::h2(_("Page Locked")),
442 HTML::p(_("This page has been locked by the administrator so your changes can not be saved.")),
443 HTML::p(_("(Copy your changes to the clipboard. You can try editing a different page or save your text in a text editor.)")),
444 HTML::p(_("Sorry for the inconvenience.")));
447 function getConflictMessage ($unresolved = false) {
449 xgettext only knows about c/c++ line-continuation strings
450 it does not know about php's dot operator.
451 We want to translate this entire paragraph as one string, of course.
454 //$re_edit_link = Button('edit', _("Edit the new version"), $this->page);
457 $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.",
458 "<<<<<<< ". _("Your version"),
459 ">>>>>>> ". _("Other version")));
461 $message = HTML::p(_("Please check it through before saving."));
465 /*$steps = HTML::ol(HTML::li(_("Copy your changes to the clipboard or to another temporary place (e.g. text editor).")),
466 HTML::li(fmt("%s of the page. You should now see the most current version of the page. Your changes are no longer there.",
468 HTML::li(_("Make changes to the file again. Paste your additions from the clipboard (or text editor).")),
469 HTML::li(_("Save your updated changes.")));
472 HTML(HTML::h2(_("Conflicting Edits!")),
473 HTML::p(_("In the time since you started editing this page, another user has saved a new version of it.")),
474 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.")),
479 function getTextArea () {
480 $request = &$this->request;
482 // wrap=virtual is not HTML4, but without it NS4 doesn't wrap
484 $readonly = ! $this->canEdit(); // || $this->isConcurrentUpdate();
486 $html = $this->getPreview();
487 $this->_wikicontent = $this->_content;
488 $this->_content = $html->asXML();
490 $textarea = HTML::textarea(array('class' => 'wikiedit',
491 'name' => 'edit[content]',
492 'id' => 'edit[content]',
493 'rows' => $request->getPref('editHeight'),
494 'cols' => $request->getPref('editWidth'),
495 'readonly' => (bool) $readonly,
496 'wrap' => 'virtual'),
499 return Edit_HtmlArea_Textarea($textarea,$this->_wikicontent,'edit[content]');
504 function getFormElements () {
505 $request = &$this->request;
506 $page = &$this->page;
509 $h = array('action' => 'edit',
510 'pagename' => $page->getName(),
511 'version' => $this->version,
512 'edit[pagetype]' => $this->meta['pagetype'],
513 'edit[current_version]' => $this->_currentVersion);
515 $el['HIDDEN_INPUTS'] = HiddenInputs($h);
518 $el['EDIT_TEXTAREA'] = $this->getTextArea();
521 = HTML::input(array('type' => 'text',
522 'class' => 'wikitext',
523 'name' => 'edit[summary]',
526 'value' => $this->meta['summary']));
528 = HTML::input(array('type' => 'checkbox',
529 'name' => 'edit[minor_edit]',
530 'checked' => (bool) $this->meta['is_minor_edit']));
532 = HTML::input(array('type' => 'checkbox',
533 'name' => 'edit[markup]',
535 'checked' => $this->meta['markup'] < 2.0,
536 'id' => 'useOldMarkup',
537 'onclick' => 'showOldMarkupRules(this.checked)'));
540 = HTML::input(array('type' => 'checkbox',
541 'name' => 'edit[locked]',
542 'disabled' => (bool) !$this->user->isadmin(),
543 'checked' => (bool) $this->locked));
545 $el['PREVIEW_B'] = Button('submit:edit[preview]', _("Preview"),
548 //if (!$this->isConcurrentUpdate() && $this->canEdit())
549 $el['SAVE_B'] = Button('submit:edit[save]', _("Save"), 'wikiaction');
551 $el['IS_CURRENT'] = $this->version == $this->current->getVersion();
556 function _redirectToBrowsePage() {
557 $this->request->redirect(WikiURL($this->page, false, 'absolute_url'));
561 function _restoreState () {
562 $request = &$this->request;
564 $posted = $request->getArg('edit');
565 $request->setArg('edit', false);
567 if (!$posted || !$request->isPost()
568 || $request->getArg('action') != 'edit')
571 if (!isset($posted['content']) || !is_string($posted['content']))
573 $this->_content = preg_replace('/[ \t\r]+\n/', "\n",
574 rtrim($posted['content']));
575 $this->_content = $this->getContent();
577 $this->_currentVersion = (int) $posted['current_version'];
579 if ($this->_currentVersion < 0)
581 if ($this->_currentVersion > $this->current->getVersion())
582 return false; // FIXME: some kind of warning?
584 $is_old_markup = !empty($posted['markup']) && $posted['markup'] == 'old';
585 $meta['markup'] = $is_old_markup ? false : 2.0;
586 $meta['summary'] = trim(substr($posted['summary'], 0, 256));
587 $meta['is_minor_edit'] = !empty($posted['minor_edit']);
588 $meta['pagetype'] = !empty($posted['pagetype']) ? $posted['pagetype'] : false;
589 $this->meta = array_merge($this->meta, $meta);
590 $this->locked = !empty($posted['locked']);
592 if (!empty($posted['preview']))
593 $this->editaction = 'preview';
594 elseif (!empty($posted['save']))
595 $this->editaction = 'save';
597 $this->editaction = 'edit';
602 function _initializeState () {
603 $request = &$this->request;
604 $current = &$this->current;
605 $selected = &$this->selected;
606 $user = &$this->user;
609 NoSuchRevision($request, $this->page, $this->version); // noreturn
611 $this->_currentVersion = $current->getVersion();
612 $this->_content = $selected->getPackedContent();
614 $this->meta['summary'] = '';
615 $this->locked = $this->page->get('locked');
617 // If author same as previous author, default minor_edit to on.
618 $age = $this->meta['mtime'] - $current->get('mtime');
619 $this->meta['is_minor_edit'] = ( $age < MINOR_EDIT_TIMEOUT
620 && $current->get('author') == $user->getId()
623 // Default for new pages is new-style markup.
624 if ($selected->hasDefaultContents())
625 $is_new_markup = true;
627 $is_new_markup = $selected->get('markup') >= 2.0;
629 $this->meta['markup'] = $is_new_markup ? 2.0: false;
630 $this->meta['pagetype'] = $selected->get('pagetype');
631 $this->editaction = 'edit';
635 class LoadFileConflictPageEditor
638 function editPage ($saveFailed = true) {
639 $tokens = &$this->tokens;
641 if (!$this->canEdit()) {
642 if ($this->isInitialEdit())
643 return $this->viewSource();
644 $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
646 elseif ($this->editaction == 'save') {
647 if ($this->savePage())
648 return true; // Page saved.
652 if ($saveFailed || $this->isConcurrentUpdate())
654 // Get the text of the original page, and the two conflicting edits
655 // The diff class takes arrays as input. So retrieve content as
656 // an array, or convert it as necesary.
657 $orig = $this->page->getRevision($this->_currentVersion);
658 $this_content = explode("\n", $this->_content);
659 $other_content = $this->current->getContent();
660 include_once("lib/diff.php");
661 $diff2 = new Diff($other_content, $this_content);
662 $context_lines = max(4, count($other_content) + 1,
663 count($this_content) + 1);
664 $fmt = new BlockDiffFormatter($context_lines);
666 $this->_content = $fmt->format($diff2);
667 // FIXME: integrate this into class BlockDiffFormatter
668 $this->_content = str_replace(">>>>>>>\n<<<<<<<\n", "=======\n",
670 $this->_content = str_replace("<<<<<<<\n>>>>>>>\n", "=======\n",
673 $this->_currentVersion = $this->current->getVersion();
674 $this->version = $this->_currentVersion;
675 $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage();
678 if ($this->editaction == 'preview')
679 $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
681 // FIXME: NOT_CURRENT_MESSAGE?
683 $tokens = array_merge($tokens, $this->getFormElements());
685 return $this->output('editpage', _("Merge and Edit: %s"));
686 // FIXME: this doesn't display
689 function output ($template, $title_fs) {
690 $selected = &$this->selected;
691 $current = &$this->current;
693 if ($selected && $selected->getVersion() != $current->getVersion()) {
695 $pagelink = WikiLink($selected);
699 $pagelink = WikiLink($this->page);
702 $title = new FormattedText ($title_fs, $pagelink);
703 $template = Template($template, $this->tokens);
705 //GeneratePage($template, $title, $rev);
709 function getConflictMessage () {
710 $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.",
713 HTML::p(_("Please check it through before saving."))));
719 $Log: not supported by cvs2svn $
720 Revision _1.6 2004/05/26 15:48:00 syilek
721 fixed problem with creating page with slashes from one true page
723 Revision _1.5 2004/05/25 16:51:53 syilek
724 added ability to create a page from the category page and not have to edit it
726 Revision 1.67 2004/05/27 17:49:06 rurban
727 renamed DB_Session to DbSession (in CVS also)
728 added WikiDB->getParam and WikiDB->getAuthParam method to get rid of globals
729 remove leading slash in error message
730 added force_unlock parameter to File_Passwd (no return on stale locks)
731 fixed adodb session AffectedRows
732 added FileFinder helpers to unify local filenames and DATA_PATH names
733 editpage.php: new edit toolbar javascript on ENABLE_EDIT_TOOLBAR
735 Revision 1.66 2004/04/29 23:25:12 rurban
736 re-ordered locale init (as in 1.3.9)
737 fixed loadfile with subpages, and merge/restore anyway
740 Revision 1.65 2004/04/18 01:11:52 rurban
741 more numeric pagename fixes.
742 fixed action=upload with merge conflict warnings.
743 charset changed from constant to global (dynamic utf-8 switching)
745 Revision 1.64 2004/04/06 19:48:56 rurban
746 temp workaround for action=edit AddComment form
748 Revision 1.63 2004/03/24 19:39:02 rurban
749 php5 workaround code (plus some interim debugging code in XmlElement)
750 php5 doesn't work yet with the current XmlElement class constructors,
751 WikiUserNew does work better than php4.
752 rewrote WikiUserNew user upgrading to ease php5 update
753 fixed pref handling in WikiUserNew
754 added Email Notification
755 added simple Email verification
756 removed emailVerify userpref subclass: just a email property
757 changed pref binary storage layout: numarray => hash of non default values
758 print optimize message only if really done.
759 forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
760 prefs should be stored in db or homepage, besides the current session.
762 Revision 1.62 2004/03/17 18:41:05 rurban
763 initial_content and template support for CreatePage
765 Revision 1.61 2004/03/12 20:59:17 rurban
766 important cookie fix by Konstantin Zadorozhny
767 new editpage feature: JS_SEARCHREPLACE
769 Revision 1.60 2004/02/15 21:34:37 rurban
770 PageList enhanced and improved.
771 fixed new WikiAdmin... plugins
772 editpage, Theme with exp. htmlarea framework
773 (htmlarea yet committed, this is really questionable)
774 WikiUser... code with better session handling for prefs
775 enhanced UserPreferences (again)
776 RecentChanges for show_deleted: how should pages be deleted then?
778 Revision 1.59 2003/12/07 20:35:26 carstenklapp
779 Bugfix: Concurrent updates broken since after 1.3.4 release: Fatal
780 error: Call to undefined function: gettransformedcontent() in
781 /home/groups/p/ph/phpwiki/htdocs/phpwiki2/lib/editpage.php on line
784 Revision 1.58 2003/03/10 18:25:22 dairiki
785 Bug/typo fix. If you use the edit page to un/lock a page, it
786 failed with: Fatal error: Call to a member function on a
787 non-object in editpage.php on line 136
789 Revision 1.57 2003/02/26 03:40:22 dairiki
790 New action=create. Essentially the same as action=edit, except that if the
791 page already exists, it falls back to action=browse.
793 This is for use in the "question mark" links for unknown wiki words
794 to avoid problems and confusion when following links from stale pages.
795 (If the "unknown page" has been created in the interim, the user probably
796 wants to view the page before editing it.)
798 Revision 1.56 2003/02/21 18:07:14 dairiki
799 Minor, nitpicky, currently inconsequential changes.
801 Revision 1.55 2003/02/21 04:10:58 dairiki
802 Fixes for new cached markup.
803 Some minor code cleanups.
805 Revision 1.54 2003/02/16 19:47:16 dairiki
806 Update WikiDB timestamp when editing or deleting pages.
808 Revision 1.53 2003/02/15 23:20:27 dairiki
809 Redirect back to browse current version of page upon save,
810 even when no changes were made.
812 Revision 1.52 2003/01/03 22:22:00 carstenklapp
813 Minor adjustments to diff block markers ("<<<<<<<"). Source reformatting.
815 Revision 1.51 2003/01/03 02:43:26 carstenklapp
816 New class LoadFileConflictPageEditor, for merging / comparing a loaded
817 pgsrc file with an existing page.
825 // c-hanging-comment-ender-p: nil
826 // indent-tabs-mode: nil