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