]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/editpage.php
re-ordered locale init (as in 1.3.9)
[SourceForge/phpwiki.git] / lib / editpage.php
1 <?php
2 rcs_id('$Id: editpage.php,v 1.66 2004-04-29 23:25:12 rurban Exp $');
3
4 require_once('lib/Template.php');
5
6 // Not yet enabled, since we cannot convert HTML to Wiki Markup yet.
7 // We might use a HTML PageType, which is contra wiki, but some people might prefer HTML markup.
8 // Todo: change from constant to user preference variable. (or checkbox setting)
9 if (!defined('USE_HTMLAREA')) define('USE_HTMLAREA',false);
10 if (USE_HTMLAREA) require_once('lib/htmlarea.php');
11
12 class PageEditor
13 {
14     function PageEditor (&$request) {
15         $this->request = &$request;
16
17         $this->user = $request->getUser();
18         $this->page = $request->getPage();
19
20         $this->current = $this->page->getCurrentRevision();
21
22         // HACKish short circuit to browse on action=create
23         if ($request->getArg('action') == 'create') {
24             if (! $this->current->hasDefaultContents()) 
25                 $request->redirect(WikiURL($this->page->getName())); // noreturn
26         }
27         
28         
29         $this->meta = array('author' => $this->user->getId(),
30                             'author_id' => $this->user->getAuthenticatedId(),
31                             'mtime' => time());
32         
33         $this->tokens = array();
34         
35         $version = $request->getArg('version');
36         if ($version !== false) {
37             $this->selected = $this->page->getRevision($version);
38             $this->version = $version;
39         }
40         else {
41             $this->selected = $this->current;
42             $this->version = $this->current->getVersion();
43         }
44
45         if ($this->_restoreState()) {
46             $this->_initialEdit = false;
47         }
48         else {
49             $this->_initializeState();
50             $this->_initialEdit = true;
51
52             // The edit request has specified some initial content from a template 
53             if (  ($template = $request->getArg('template')) and 
54                   $request->_dbi->isWikiPage($template)) {
55                 $page = $request->_dbi->getPage($template);
56                 $current = $page->getCurrentRevision();
57                 $this->_content = $current->getPackedContent();
58             } elseif ($initial_content = $request->getArg('initial_content')) {
59                 $this->_content = $initial_content;
60             }
61         }
62         if (!headers_sent())
63             header("Content-Type: text/html; charset=" . $GLOBALS['charset']);
64     }
65
66     function editPage () {
67         $saveFailed = false;
68         $tokens = &$this->tokens;
69
70         if (! $this->canEdit()) {
71             if ($this->isInitialEdit())
72                 return $this->viewSource();
73             $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
74         }
75         elseif ($this->editaction == 'save') {
76             if ($this->savePage())
77                 return true;    // Page saved.
78             $saveFailed = true;
79         }
80
81         if ($saveFailed || $this->isConcurrentUpdate())
82         {
83             // Get the text of the original page, and the two conflicting edits
84             // The diff3 class takes arrays as input.  So retrieve content as
85             // an array, or convert it as necesary.
86             $orig = $this->page->getRevision($this->_currentVersion);
87             // FIXME: what if _currentVersion has be deleted?
88             $orig_content = $orig->getContent();
89             $this_content = explode("\n", $this->_content);
90             $other_content = $this->current->getContent();
91             include_once("lib/diff3.php");
92             $diff = new diff3($orig_content, $this_content, $other_content);
93             $output = $diff->merged_output(_("Your version"), _("Other version"));
94             // Set the content of the textarea to the merged diff
95             // output, and update the version
96             $this->_content = implode ("\n", $output);
97             $this->_currentVersion = $this->current->getVersion();
98             $this->version = $this->_currentVersion;
99             $unresolved = $diff->ConflictingBlocks;
100             $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage($unresolved);
101         }
102
103         if ($this->editaction == 'preview')
104             $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
105
106         // FIXME: NOT_CURRENT_MESSAGE?
107
108         $tokens = array_merge($tokens, $this->getFormElements());
109
110         if (defined('JS_SEARCHREPLACE') and JS_SEARCHREPLACE) {
111             $tokens['JS_SEARCHREPLACE'] = 1;
112             $GLOBALS['Theme']->addMoreHeaders(Javascript("
113 var wart=0, d, f, x='', replacewin, pretxt=new Array(), pretxt_anzahl=0;
114 var fag='<font face=\"arial,helvetica,sans-serif\" size=\"-1\">', fr='<font color=\"#cc0000\">', spn='<span class=\"grey\">';
115
116 function define_f() {
117    f=document.getElementById('editpage');
118    f.editarea=document.getElementById('edit[content]');
119    if(f.rck.style) f.rck.style.color='#ececec';
120 }
121
122 function replace() {
123    replacewin=window.open('','','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,height=90,width=450');
124    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()\">&nbsp;&nbsp;&nbsp;<input class=\"btt\" type=\"button\" value=\""._("Close")."\" onclick=\"self.close()\"></td></tr></table></center></form></body></html>');
125    replacewin.window.document.close();
126 }
127
128 function do_replace() {
129    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;
130    if(ein==''||ein==null) {
131       replacewin.window.document.forms[0].ein.focus();
132       return;
133    }
134    var z_repl=txt.match(ein)? txt.match(ein).length : 0;
135    txt=txt.replace(ein,aus);
136    ein=ein.toString().substring(1,ein.toString().length-2);
137    result(z_repl, 'Substring \"'+ein+'\" found '+z_repl+' times. Replace with \"'+aus+'\"?', txt, 'String \"'+ein+'\" not found.');
138    replacewin.window.focus();
139    replacewin.window.document.forms[0].ein.focus();
140 }
141 function result(zahl,frage,txt,alert_txt) {
142    if(wart!=0&&wart.window) {
143       wart.window.close();
144       wart=0;
145    }
146    if(zahl>0) {
147       if(window.confirm(frage)==true) {
148          f.editarea.value=txt;
149          pretxt_anzahl++;
150          if(f.rck.style) f.rck.style.color='#000000';
151          f.rck.value='"._("Undo")."';
152       }
153    } else alert(alert_txt);
154 }
155 function rueck() {
156    if(pretxt_anzahl==0) return;
157    else if(pretxt_anzahl>0) {
158       f.editarea.value=pretxt[pretxt_anzahl-1];
159       pretxt[pretxt_anzahl]=null;
160       pretxt_anzahl--;
161       if(pretxt_anzahl==0) {
162          alert('Operation undone.');
163          if(f.rck.style) f.rck.style.color='#ececec';
164          f.rck.value='("._("Undo").")';
165          if(f.rck.blur) f.rck.blur();
166       }
167    }
168 }
169 function speich() {
170    pretxt[pretxt_anzahl]=f.editarea.value;
171    pretxt_anzahl++;
172    if(f.rck.style) f.rck.style.color='#000000';
173    f.rck.value='"._("Undo")."';
174 }
175 "));
176             $GLOBALS['Theme']->addMoreAttr('body'," onload='define_f()'");
177         }
178
179         return $this->output('editpage', _("Edit: %s"));
180     }
181
182     function output ($template, $title_fs) {
183         global $Theme;
184         $selected = &$this->selected;
185         $current = &$this->current;
186
187         if ($selected && $selected->getVersion() != $current->getVersion()) {
188             $rev = $selected;
189             $pagelink = WikiLink($selected);
190         }
191         else {
192             $rev = $current;
193             $pagelink = WikiLink($this->page);
194         }
195
196
197         $title = new FormattedText ($title_fs, $pagelink);
198         if ($template == 'editpage' and USE_HTMLAREA) {
199             $Theme->addMoreHeaders(Edit_HtmlArea_Head());
200             //$tokens['PAGE_SOURCE'] = Edit_HtmlArea_ConvertBefore($this->_content);
201         }
202         $template = Template($template, $this->tokens);
203         GeneratePage($template, $title, $rev);
204         return true;
205     }
206
207
208     function viewSource () {
209         assert($this->isInitialEdit());
210         assert($this->selected);
211
212         $this->tokens['PAGE_SOURCE'] = $this->_content;
213         return $this->output('viewsource', _("View Source: %s"));
214     }
215
216     function updateLock() {
217         if ((bool)$this->page->get('locked') == (bool)$this->locked)
218             return false;       // Not changed.
219
220         if (!$this->user->isAdmin()) {
221             // FIXME: some sort of message
222             return false;         // not allowed.
223         }
224
225         $this->page->set('locked', (bool)$this->locked);
226         $this->tokens['LOCK_CHANGED_MSG']
227             = $this->locked ? _("Page now locked.") : _("Page now unlocked.");
228
229         return true;            // lock changed.
230     }
231
232     function savePage () {
233         $request = &$this->request;
234
235         if ($this->isUnchanged()) {
236             // Allow admin lock/unlock even if
237             // no text changes were made.
238             if ($this->updateLock()) {
239                 $dbi = $request->getDbh();
240                 $dbi->touch();
241             }
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');
249             return true;
250         }
251
252         $page = &$this->page;
253
254         // Include any meta-data from original page version which
255         // has not been explicitly updated.
256         // (Except don't propagate pgsrc_version --- moot for now,
257         //  because at present it never gets into the db...)
258         $meta = $this->selected->getMetaData();
259         unset($meta['pgsrc_version']);
260         $meta = array_merge($meta, $this->meta);
261         
262         // Save new revision
263         $this->_content = $this->getContent();
264         $newrevision = $page->save($this->_content, $this->_currentVersion + 1, $meta);
265         if (!isa($newrevision, 'wikidb_pagerevision')) {
266             // Save failed.  (Concurrent updates).
267             return false;
268         }
269         
270         // New contents successfully saved...
271         $this->updateLock();
272
273         // Clean out archived versions of this page.
274         include_once('lib/ArchiveCleaner.php');
275         $cleaner = new ArchiveCleaner($GLOBALS['ExpireParams']);
276         $cleaner->cleanPageRevisions($page);
277
278         /* generate notification emails done in WikiDB::save to catch all direct calls 
279           (admin plugins) */
280
281         $dbi = $request->getDbh();
282         $warnings = $dbi->GenericWarnings();
283         $dbi->touch();
284         
285         global $Theme;
286         if (empty($warnings) && ! $Theme->getImageURL('signature')) {
287             // Do redirect to browse page if no signature has
288             // been defined.  In this case, the user will most
289             // likely not see the rest of the HTML we generate
290             // (below).
291             $this->_redirectToBrowsePage();
292         }
293
294         // Force browse of current page version.
295         $request->setArg('version', false);
296         //$request->setArg('action', false);
297
298         $template = Template('savepage', $this->tokens);
299         $template->replace('CONTENT', $newrevision->getTransformedContent());
300         if (!empty($warnings))
301             $template->replace('WARNINGS', $warnings);
302
303         $pagelink = WikiLink($page);
304
305         GeneratePage($template, fmt("Saved: %s", $pagelink), $newrevision);
306         return true;
307     }
308
309     function isConcurrentUpdate () {
310         assert($this->current->getVersion() >= $this->_currentVersion);
311         return $this->current->getVersion() != $this->_currentVersion;
312     }
313
314     function canEdit () {
315         return !$this->page->get('locked') || $this->user->isAdmin();
316     }
317
318     function isInitialEdit () {
319         return $this->_initialEdit;
320     }
321
322     function isUnchanged () {
323         $current = &$this->current;
324
325         if ($this->meta['markup'] !=  $current->get('markup'))
326             return false;
327
328         return $this->_content == $current->getPackedContent();
329     }
330
331     function getPreview () {
332         include_once('lib/PageType.php');
333         $this->_content = $this->getContent();
334         return new TransformedText($this->page, $this->_content, $this->meta);
335     }
336
337     // possibly convert HTMLAREA content back to Wiki markup
338     function getContent () {
339         if (USE_HTMLAREA) {
340             $xml_output = Edit_HtmlArea_ConvertAfter($this->_content);
341             $this->_content = join("",$xml_output->_content);
342             return $this->_content;
343         } else {
344             return $this->_content;
345         }
346     }
347
348     function getLockedMessage () {
349         return
350             HTML(HTML::h2(_("Page Locked")),
351                  HTML::p(_("This page has been locked by the administrator so your changes can not be saved.")),
352                  HTML::p(_("(Copy your changes to the clipboard. You can try editing a different page or save your text in a text editor.)")),
353                  HTML::p(_("Sorry for the inconvenience.")));
354     }
355
356     function getConflictMessage ($unresolved = false) {
357         /*
358          xgettext only knows about c/c++ line-continuation strings
359          it does not know about php's dot operator.
360          We want to translate this entire paragraph as one string, of course.
361          */
362
363         //$re_edit_link = Button('edit', _("Edit the new version"), $this->page);
364
365         if ($unresolved)
366             $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.",
367                                 "<<<<<<< ". _("Your version"),
368                                 ">>>>>>> ". _("Other version")));
369         else
370             $message = HTML::p(_("Please check it through before saving."));
371
372
373
374         /*$steps = HTML::ol(HTML::li(_("Copy your changes to the clipboard or to another temporary place (e.g. text editor).")),
375           HTML::li(fmt("%s of the page. You should now see the most current version of the page. Your changes are no longer there.",
376                        $re_edit_link)),
377           HTML::li(_("Make changes to the file again. Paste your additions from the clipboard (or text editor).")),
378           HTML::li(_("Save your updated changes.")));
379         */
380         return
381             HTML(HTML::h2(_("Conflicting Edits!")),
382                  HTML::p(_("In the time since you started editing this page, another user has saved a new version of it.")),
383                  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.")),
384                  $message);
385     }
386
387
388     function getTextArea () {
389         $request = &$this->request;
390
391         // wrap=virtual is not HTML4, but without it NS4 doesn't wrap
392         // long lines
393         $readonly = ! $this->canEdit(); // || $this->isConcurrentUpdate();
394         if (USE_HTMLAREA) {
395             $html = $this->getPreview();
396             $this->_wikicontent = $this->_content;
397             $this->_content = $html->asXML();
398         }
399         $textarea = HTML::textarea(array('class' => 'wikiedit',
400                                          'name' => 'edit[content]',
401                                          'id'   => 'edit[content]',
402                                          'rows' => $request->getPref('editHeight'),
403                                          'cols' => $request->getPref('editWidth'),
404                                          'readonly' => (bool) $readonly,
405                                          'wrap' => 'virtual'),
406                                    $this->_content);
407         if (USE_HTMLAREA)
408             return Edit_HtmlArea_Textarea($textarea,$this->_wikicontent,'edit[content]');
409         else
410             return $textarea;
411     }
412
413     function getFormElements () {
414         $request = &$this->request;
415         $page = &$this->page;
416
417
418         $h = array('action'   => 'edit',
419                    'pagename' => $page->getName(),
420                    'version'  => $this->version,
421                    'edit[pagetype]' => $this->meta['pagetype'],
422                    'edit[current_version]' => $this->_currentVersion);
423
424         $el['HIDDEN_INPUTS'] = HiddenInputs($h);
425
426
427         $el['EDIT_TEXTAREA'] = $this->getTextArea();
428
429         $el['SUMMARY_INPUT']
430             = HTML::input(array('type'  => 'text',
431                                 'class' => 'wikitext',
432                                 'name'  => 'edit[summary]',
433                                 'size'  => 50,
434                                 'maxlength' => 256,
435                                 'value' => $this->meta['summary']));
436         $el['MINOR_EDIT_CB']
437             = HTML::input(array('type' => 'checkbox',
438                                 'name'  => 'edit[minor_edit]',
439                                 'checked' => (bool) $this->meta['is_minor_edit']));
440         $el['OLD_MARKUP_CB']
441             = HTML::input(array('type' => 'checkbox',
442                                 'name' => 'edit[markup]',
443                                 'value' => 'old',
444                                 'checked' => $this->meta['markup'] < 2.0,
445                                 'id' => 'useOldMarkup',
446                                 'onclick' => 'showOldMarkupRules(this.checked)'));
447
448         $el['LOCKED_CB']
449             = HTML::input(array('type' => 'checkbox',
450                                 'name' => 'edit[locked]',
451                                 'disabled' => (bool) !$this->user->isadmin(),
452                                 'checked'  => (bool) $this->locked));
453
454         $el['PREVIEW_B'] = Button('submit:edit[preview]', _("Preview"),
455                                   'wikiaction');
456
457         //if (!$this->isConcurrentUpdate() && $this->canEdit())
458         $el['SAVE_B'] = Button('submit:edit[save]', _("Save"), 'wikiaction');
459
460         $el['IS_CURRENT'] = $this->version == $this->current->getVersion();
461
462         return $el;
463     }
464
465     function _redirectToBrowsePage() {
466         $this->request->redirect(WikiURL($this->page, false, 'absolute_url'));
467     }
468     
469
470     function _restoreState () {
471         $request = &$this->request;
472
473         $posted = $request->getArg('edit');
474         $request->setArg('edit', false);
475
476         if (!$posted || !$request->isPost()
477             || $request->getArg('action') != 'edit')
478             return false;
479
480         if (!isset($posted['content']) || !is_string($posted['content']))
481             return false;
482         $this->_content = preg_replace('/[ \t\r]+\n/', "\n",
483                                         rtrim($posted['content']));
484         $this->_content = $this->getContent();
485
486         $this->_currentVersion = (int) $posted['current_version'];
487
488         if ($this->_currentVersion < 0)
489             return false;
490         if ($this->_currentVersion > $this->current->getVersion())
491             return false;       // FIXME: some kind of warning?
492
493         $is_old_markup = !empty($posted['markup']) && $posted['markup'] == 'old';
494         $meta['markup'] = $is_old_markup ? false : 2.0;
495         $meta['summary'] = trim(substr($posted['summary'], 0, 256));
496         $meta['is_minor_edit'] = !empty($posted['minor_edit']);
497         $meta['pagetype'] = !empty($posted['pagetype']) ? $posted['pagetype'] : false;
498         $this->meta = array_merge($this->meta, $meta);
499         $this->locked = !empty($posted['locked']);
500
501         if (!empty($posted['preview']))
502             $this->editaction = 'preview';
503         elseif (!empty($posted['save']))
504             $this->editaction = 'save';
505         else
506             $this->editaction = 'edit';
507
508         return true;
509     }
510
511     function _initializeState () {
512         $request = &$this->request;
513         $current = &$this->current;
514         $selected = &$this->selected;
515         $user = &$this->user;
516
517         if (!$selected)
518             NoSuchRevision($request, $this->page, $this->version); // noreturn
519
520         $this->_currentVersion = $current->getVersion();
521         $this->_content = $selected->getPackedContent();
522
523         $this->meta['summary'] = '';
524         $this->locked = $this->page->get('locked');
525
526         // If author same as previous author, default minor_edit to on.
527         $age = $this->meta['mtime'] - $current->get('mtime');
528         $this->meta['is_minor_edit'] = ( $age < MINOR_EDIT_TIMEOUT
529                                          && $current->get('author') == $user->getId()
530                                          );
531
532         // Default for new pages is new-style markup.
533         if ($selected->hasDefaultContents())
534             $is_new_markup = true;
535         else
536             $is_new_markup = $selected->get('markup') >= 2.0;
537
538         $this->meta['markup'] = $is_new_markup ? 2.0: false;
539         $this->meta['pagetype'] = $selected->get('pagetype');
540         $this->editaction = 'edit';
541     }
542 }
543
544 class LoadFileConflictPageEditor
545 extends PageEditor
546 {
547     function editPage ($saveFailed = true) {
548         $tokens = &$this->tokens;
549
550         if (!$this->canEdit()) {
551             if ($this->isInitialEdit())
552                 return $this->viewSource();
553             $tokens['PAGE_LOCKED_MESSAGE'] = $this->getLockedMessage();
554         }
555         elseif ($this->editaction == 'save') {
556             if ($this->savePage())
557                 return true;    // Page saved.
558             $saveFailed = true;
559         }
560
561         if ($saveFailed || $this->isConcurrentUpdate())
562         {
563             // Get the text of the original page, and the two conflicting edits
564             // The diff class takes arrays as input.  So retrieve content as
565             // an array, or convert it as necesary.
566             $orig = $this->page->getRevision($this->_currentVersion);
567             $this_content = explode("\n", $this->_content);
568             $other_content = $this->current->getContent();
569             include_once("lib/diff.php");
570             $diff2 = new Diff($other_content, $this_content);
571             $context_lines = max(4, count($other_content) + 1,
572                                  count($this_content) + 1);
573             $fmt = new BlockDiffFormatter($context_lines);
574
575             $this->_content = $fmt->format($diff2);
576             // FIXME: integrate this into class BlockDiffFormatter
577             $this->_content = str_replace(">>>>>>>\n<<<<<<<\n", "=======\n",
578                                           $this->_content);
579             $this->_content = str_replace("<<<<<<<\n>>>>>>>\n", "=======\n",
580                                           $this->_content);
581
582             $this->_currentVersion = $this->current->getVersion();
583             $this->version = $this->_currentVersion;
584             $tokens['CONCURRENT_UPDATE_MESSAGE'] = $this->getConflictMessage();
585         }
586
587         if ($this->editaction == 'preview')
588             $tokens['PREVIEW_CONTENT'] = $this->getPreview(); // FIXME: convert to _MESSAGE?
589
590         // FIXME: NOT_CURRENT_MESSAGE?
591
592         $tokens = array_merge($tokens, $this->getFormElements());
593
594         return $this->output('editpage', _("Merge and Edit: %s"));
595         // FIXME: this doesn't display
596     }
597
598     function output ($template, $title_fs) {
599         $selected = &$this->selected;
600         $current = &$this->current;
601
602         if ($selected && $selected->getVersion() != $current->getVersion()) {
603             $rev = $selected;
604             $pagelink = WikiLink($selected);
605         }
606         else {
607             $rev = $current;
608             $pagelink = WikiLink($this->page);
609         }
610
611         $title = new FormattedText ($title_fs, $pagelink);
612         $template = Template($template, $this->tokens);
613
614         //GeneratePage($template, $title, $rev);
615         PrintXML($template);
616         return true;
617     }
618     function getConflictMessage () {
619         $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.",
620                                     "<<<<<<<",
621                                     "======="),
622                                 HTML::p(_("Please check it through before saving."))));
623         return $message;
624     }
625 }
626
627 /**
628  $Log: not supported by cvs2svn $
629  Revision 1.65  2004/04/18 01:11:52  rurban
630  more numeric pagename fixes.
631  fixed action=upload with merge conflict warnings.
632  charset changed from constant to global (dynamic utf-8 switching)
633
634  Revision 1.64  2004/04/06 19:48:56  rurban
635  temp workaround for action=edit AddComment form
636
637  Revision 1.63  2004/03/24 19:39:02  rurban
638  php5 workaround code (plus some interim debugging code in XmlElement)
639    php5 doesn't work yet with the current XmlElement class constructors,
640    WikiUserNew does work better than php4.
641  rewrote WikiUserNew user upgrading to ease php5 update
642  fixed pref handling in WikiUserNew
643  added Email Notification
644  added simple Email verification
645  removed emailVerify userpref subclass: just a email property
646  changed pref binary storage layout: numarray => hash of non default values
647  print optimize message only if really done.
648  forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
649    prefs should be stored in db or homepage, besides the current session.
650
651  Revision 1.62  2004/03/17 18:41:05  rurban
652  initial_content and template support for CreatePage
653
654  Revision 1.61  2004/03/12 20:59:17  rurban
655  important cookie fix by Konstantin Zadorozhny
656  new editpage feature: JS_SEARCHREPLACE
657
658  Revision 1.60  2004/02/15 21:34:37  rurban
659  PageList enhanced and improved.
660  fixed new WikiAdmin... plugins
661  editpage, Theme with exp. htmlarea framework
662    (htmlarea yet committed, this is really questionable)
663  WikiUser... code with better session handling for prefs
664  enhanced UserPreferences (again)
665  RecentChanges for show_deleted: how should pages be deleted then?
666
667  Revision 1.59  2003/12/07 20:35:26  carstenklapp
668  Bugfix: Concurrent updates broken since after 1.3.4 release: Fatal
669  error: Call to undefined function: gettransformedcontent() in
670  /home/groups/p/ph/phpwiki/htdocs/phpwiki2/lib/editpage.php on line
671  205.
672
673  Revision 1.58  2003/03/10 18:25:22  dairiki
674  Bug/typo fix.  If you use the edit page to un/lock a page, it
675  failed with: Fatal error: Call to a member function on a
676  non-object in editpage.php on line 136
677
678  Revision 1.57  2003/02/26 03:40:22  dairiki
679  New action=create.  Essentially the same as action=edit, except that if the
680  page already exists, it falls back to action=browse.
681
682  This is for use in the "question mark" links for unknown wiki words
683  to avoid problems and confusion when following links from stale pages.
684  (If the "unknown page" has been created in the interim, the user probably
685  wants to view the page before editing it.)
686
687  Revision 1.56  2003/02/21 18:07:14  dairiki
688  Minor, nitpicky, currently inconsequential changes.
689
690  Revision 1.55  2003/02/21 04:10:58  dairiki
691  Fixes for new cached markup.
692  Some minor code cleanups.
693
694  Revision 1.54  2003/02/16 19:47:16  dairiki
695  Update WikiDB timestamp when editing or deleting pages.
696
697  Revision 1.53  2003/02/15 23:20:27  dairiki
698  Redirect back to browse current version of page upon save,
699  even when no changes were made.
700
701  Revision 1.52  2003/01/03 22:22:00  carstenklapp
702  Minor adjustments to diff block markers ("<<<<<<<"). Source reformatting.
703
704  Revision 1.51  2003/01/03 02:43:26  carstenklapp
705  New class LoadFileConflictPageEditor, for merging / comparing a loaded
706  pgsrc file with an existing page.
707
708  */
709
710 // Local Variables:
711 // mode: php
712 // tab-width: 8
713 // c-basic-offset: 4
714 // c-hanging-comment-ender-p: nil
715 // indent-tabs-mode: nil
716 // End:
717 ?>