2 rcs_id('$Id: loadsave.php,v 1.88 2004-02-22 23:20:31 rurban Exp $');
5 Copyright 1999, 2000, 2001, 2002 $ThePhpWikiProgrammingTeam
7 This file is part of PhpWiki.
9 PhpWiki is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 PhpWiki is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with PhpWiki; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 require_once("lib/ziplib.php");
26 require_once("lib/Template.php");
28 function StartLoadDump(&$request, $title, $html = '')
30 // FIXME: This is a hack
31 $tmpl = Template('html', array('TITLE' => $title,
33 'CONTENT' => '%BODY%'));
34 echo ereg_replace('%BODY%.*', '', $tmpl->getExpansion($html));
37 function EndLoadDump(&$request)
39 // FIXME: This is a hack
40 $pagelink = WikiLink($request->getPage());
42 PrintXML(HTML::p(HTML::strong(_("Complete."))),
43 HTML::p(fmt("Return to %s", $pagelink)));
44 echo "</body></html>\n";
48 ////////////////////////////////////////////////////////////////
50 // Functions for dumping.
52 ////////////////////////////////////////////////////////////////
56 * http://www.nacs.uci.edu/indiv/ehood/MIME/2045/rfc2045.html
57 * http://www.faqs.org/rfcs/rfc2045.html
58 * (RFC 1521 has been superceeded by RFC 2045 & others).
60 * Also see http://www.faqs.org/rfcs/rfc2822.html
62 function MailifyPage ($page, $nversions = 1)
64 $current = $page->getCurrentRevision();
67 if (STRICT_MAILABLE_PAGEDUMPS) {
68 $from = defined('SERVER_ADMIN') ? SERVER_ADMIN : 'foo@bar';
69 //This is for unix mailbox format: (not RFC (2)822)
70 // $head .= "From $from " . CTime(time()) . "\r\n";
71 $head .= "Subject: " . rawurlencode($page->getName()) . "\r\n";
72 $head .= "From: $from (PhpWiki)\r\n";
73 // RFC 2822 requires only a Date: and originator (From:)
74 // field, however the obsolete standard RFC 822 also
75 // requires a destination field.
76 $head .= "To: $from (PhpWiki)\r\n";
78 $head .= "Date: " . Rfc2822DateTime($current->get('mtime')) . "\r\n";
79 $head .= sprintf("Mime-Version: 1.0 (Produced by PhpWiki %s)\r\n",
82 // This should just be entered by hand (or by script?)
83 // in the actual pgsrc files, since only they should have
85 //$head .= "X-Rcs-Id: \$Id\$\r\n";
87 $iter = $page->getAllRevisions();
89 while ($revision = $iter->next()) {
90 $parts[] = MimeifyPageRevision($revision);
91 if ($nversions > 0 && count($parts) >= $nversions)
94 if (count($parts) > 1)
95 return $head . MimeMultipart($parts);
97 return $head . $parts[0];
101 * Compute filename to used for storing contents of a wiki page.
103 * Basically we do a rawurlencode() which encodes everything except
104 * ASCII alphanumerics and '.', '-', and '_'.
106 * But we also want to encode leading dots to avoid filenames like
107 * '.', and '..'. (Also, there's no point in generating "hidden" file
108 * names, like '.foo'.)
110 * @param $pagename string Pagename.
111 * @return string Filename for page.
113 function FilenameForPage ($pagename)
115 $enc = rawurlencode($pagename);
116 return preg_replace('/^\./', '%2e', $enc);
120 * The main() function which generates a zip archive of a PhpWiki.
122 * If $include_archive is false, only the current version of each page
123 * is included in the zip file; otherwise all archived versions are
126 function MakeWikiZip (&$request)
128 if ($request->getArg('include') == 'all') {
129 $zipname = WIKI_NAME . _("FullDump") . date('Ymd-Hi') . '.zip';
130 $include_archive = true;
133 $zipname = WIKI_NAME . _("LatestSnapshot") . date('Ymd-Hi') . '.zip';
134 $include_archive = false;
139 $zip = new ZipWriter("Created by PhpWiki " . PHPWIKI_VERSION, $zipname);
141 $dbi = $request->getDbh();
142 $pages = $dbi->getAllPages();
143 while ($page = $pages->next()) {
144 @set_time_limit(30); // Reset watchdog
146 $current = $page->getCurrentRevision();
147 if ($current->getVersion() == 0)
150 $wpn = new WikiPageName($page->getName());
151 if (!$wpn->isValid())
154 $attrib = array('mtime' => $current->get('mtime'),
156 if ($page->get('locked'))
157 $attrib['write_protected'] = 1;
159 if ($include_archive)
160 $content = MailifyPage($page, 0);
162 $content = MailifyPage($page);
164 $zip->addRegularFile( FilenameForPage($page->getName()),
170 function DumpToDir (&$request)
172 $directory = $request->getArg('directory');
173 if (empty($directory))
174 $request->finish(_("You must specify a directory to dump to"));
176 // see if we can access the directory the user wants us to use
177 if (! file_exists($directory)) {
178 if (! mkdir($directory, 0755))
179 $request->finish(fmt("Cannot create directory '%s'", $directory));
181 $html = HTML::p(fmt("Created directory '%s' for the page dump...",
184 $html = HTML::p(fmt("Using directory '%s'", $directory));
187 StartLoadDump($request, _("Dumping Pages"), $html);
189 $dbi = $request->getDbh();
190 $pages = $dbi->getAllPages();
192 while ($page = $pages->next()) {
193 @set_time_limit(30); // Reset watchdog.
195 $filename = FilenameForPage($page->getName());
197 $msg = HTML(HTML::br(), $page->getName(), ' ... ');
199 if($page->getName() != $filename) {
200 $msg->pushContent(HTML::small(fmt("saved as %s", $filename)),
204 if ($request->getArg('include') == 'all')
205 $data = MailifyPage($page, 0);
207 $data = MailifyPage($page);
209 if ( !($fd = fopen("$directory/$filename", "w")) ) {
210 $msg->pushContent(HTML::strong(fmt("couldn't open file '%s' for writing",
211 "$directory/$filename")));
212 $request->finish($msg);
215 $num = fwrite($fd, $data, strlen($data));
216 $msg->pushContent(HTML::small(fmt("%s bytes written", $num)));
220 assert($num == strlen($data));
224 EndLoadDump($request);
228 function DumpHtmlToDir (&$request)
230 $directory = $request->getArg('directory');
231 if (empty($directory))
232 $request->finish(_("You must specify a directory to dump to"));
234 // see if we can access the directory the user wants us to use
235 if (! file_exists($directory)) {
236 if (! mkdir($directory, 0755))
237 $request->finish(fmt("Cannot create directory '%s'", $directory));
239 $html = HTML::p(fmt("Created directory '%s' for the page dump...",
242 $html = HTML::p(fmt("Using directory '%s'", $directory));
245 StartLoadDump($request, _("Dumping Pages"), $html);
246 $thispage = $request->getArg('pagename'); // for "Return to ..."
248 $dbi = $request->getDbh();
249 $pages = $dbi->getAllPages();
251 global $HTML_DUMP_SUFFIX, $Theme;
252 if ($HTML_DUMP_SUFFIX)
253 $Theme->HTML_DUMP_SUFFIX = $HTML_DUMP_SUFFIX;
255 while ($page = $pages->next()) {
256 if (! $request->getArg('start_debug'))
257 @set_time_limit(30); // Reset watchdog.
259 $pagename = $page->getName();
260 $request->setArg('pagename',$pagename); // Template::_basepage fix
261 $filename = FilenameForPage($pagename) . $Theme->HTML_DUMP_SUFFIX;
263 $msg = HTML(HTML::br(), $pagename, ' ... ');
265 if($page->getName() != $filename) {
266 $msg->pushContent(HTML::small(fmt("saved as %s", $filename)),
270 $revision = $page->getCurrentRevision();
271 $transformedContent = $revision->getTransformedContent();
272 $template = new Template('browse', $request,
273 array('revision' => $revision,
274 'CONTENT' => $transformedContent));
276 $data = GeneratePageasXML($template, $pagename);
278 if ( !($fd = fopen("$directory/$filename", "w")) ) {
279 $msg->pushContent(HTML::strong(fmt("couldn't open file '%s' for writing",
280 "$directory/$filename")));
281 $request->finish($msg);
284 $num = fwrite($fd, $data, strlen($data));
285 $msg->pushContent(HTML::small(fmt("%s bytes written", $num), "\n"));
289 assert($num == strlen($data));
293 //CopyImageFiles() will go here;
294 $Theme->$HTML_DUMP_SUFFIX = '';
296 $request->setArg('pagename',$thispage); // Template::_basepage fix
297 EndLoadDump($request);
300 /* Known problem: any plugins or other code which echo()s text will
301 * lead to a corrupted html zip file which may produce the following
302 * errors upon unzipping:
304 * warning [wikihtml.zip]: 2401 extra bytes at beginning or within zipfile
305 * file #58: bad zipfile offset (local header sig): 177561
306 * (attempting to re-compensate)
308 * However, the actual wiki page data should be unaffected.
310 function MakeWikiZipHtml (&$request)
312 $zipname = "wikihtml.zip";
313 $zip = new ZipWriter("Created by PhpWiki " . PHPWIKI_VERSION, $zipname);
314 $dbi = $request->getDbh();
315 $pages = $dbi->getAllPages();
317 global $HTML_DUMP_SUFFIX, $Theme;
318 if ($HTML_DUMP_SUFFIX)
319 $Theme->HTML_DUMP_SUFFIX = $HTML_DUMP_SUFFIX;
321 while ($page = $pages->next()) {
322 @set_time_limit(30); // Reset watchdog.
324 $current = $page->getCurrentRevision();
325 if ($current->getVersion() == 0)
328 $attrib = array('mtime' => $current->get('mtime'),
330 if ($page->get('locked'))
331 $attrib['write_protected'] = 1;
333 $pagename = $page->getName();
334 $request->setArg('pagename',$pagename); // Template::_basepage fix
335 $filename = FilenameForPage($pagename) . $Theme->HTML_DUMP_SUFFIX;
336 $revision = $page->getCurrentRevision();
338 $transformedContent = $revision->getTransformedContent();
340 $template = new Template('browse', $request,
341 array('revision' => $revision,
342 'CONTENT' => $transformedContent));
344 $data = GeneratePageasXML($template, $pagename);
346 $zip->addRegularFile( $filename, $data, $attrib);
348 // FIXME: Deal with images here.
350 $Theme->$HTML_DUMP_SUFFIX = '';
354 ////////////////////////////////////////////////////////////////
356 // Functions for restoring.
358 ////////////////////////////////////////////////////////////////
360 function SavePage (&$request, $pageinfo, $source, $filename)
362 $pagedata = $pageinfo['pagedata']; // Page level meta-data.
363 $versiondata = $pageinfo['versiondata']; // Revision level meta-data.
365 if (empty($pageinfo['pagename'])) {
366 PrintXML(HTML::dt(HTML::strong(_("Empty pagename!"))));
370 if (empty($versiondata['author_id']))
371 $versiondata['author_id'] = $versiondata['author'];
373 $pagename = $pageinfo['pagename'];
374 $content = $pageinfo['content'];
376 if ($pagename ==_("InterWikiMap"))
377 $content = _tryinsertInterWikiMap($content);
379 $dbi = $request->getDbh();
380 $page = $dbi->getPage($pagename);
382 $current = $page->getCurrentRevision();
383 // Try to merge if updated pgsrc contents are different. This
384 // whole thing is hackish
386 // TODO: try merge unless:
387 // if (current contents = default contents && pgsrc_version >=
388 // pgsrc_version) then just upgrade this pgsrc
389 $needs_merge = false;
393 if ($request->getArg('merge')) {
396 else if ($request->getArg('overwrite')) {
400 if ( (! $current->hasDefaultContents())
401 && ($current->getPackedContent() != $content)
402 && ($merging == true) ) {
403 include_once('lib/editpage.php');
404 $request->setArg('pagename', $pagename);
405 $r = $current->getVersion();
406 $request->setArg('revision', $current->getVersion());
407 $p = new LoadFileConflictPageEditor($request);
408 $p->_content = $content;
409 $p->_currentVersion = $r - 1;
410 $p->editPage($saveFailed = true);
411 return; //early return
414 foreach ($pagedata as $key => $value) {
416 $page->set($key, $value);
422 $mesg->pushContent(' ', fmt("from %s", $source));
425 $current = $page->getCurrentRevision();
426 if ($current->getVersion() == 0) {
427 $mesg->pushContent(' ', _("new page"));
431 if ( (! $current->hasDefaultContents())
432 && ($current->getPackedContent() != $content) ) {
434 $mesg->pushContent(' ',
435 fmt("has edit conflicts - overwriting anyway"));
437 if (substr_count($source, 'pgsrc')) {
438 $versiondata['author'] = _("The PhpWiki programming team");
439 // but leave authorid as userid who loaded the file
443 $mesg->pushContent(' ', fmt("has edit conflicts - skipped"));
444 $needs_merge = true; // hackish
448 else if ($current->getPackedContent() == $content
449 && $current->get('author') == $versiondata['author']) {
450 $mesg->pushContent(' ',
451 fmt("is identical to current version %d - skipped",
452 $current->getVersion()));
459 $new = $page->save($content, WIKIDB_FORCE_CREATE, $versiondata);
461 $mesg->pushContent(' ', fmt("- saved to database as version %d",
462 $new->getVersion()));
466 // hackish, $source contains needed path+filename
467 $f = str_replace(sprintf(_("MIME file %s"), ''), '', $f);
468 $f = str_replace(sprintf(_("Serialized file %s"), ''), '', $f);
469 $f = str_replace(sprintf(_("plain file %s"), ''), '', $f);
471 $meb = Button(array('action' => 'loadfile',
473 'source'=> dirname($f) . "/"
476 _("PhpWikiAdministration"),
478 $owb = Button(array('action' => 'loadfile',
480 'source'=> dirname($f) . "/"
483 _("PhpWikiAdministration"),
485 $mesg->pushContent(' ', $meb, " ", $owb);
489 PrintXML(HTML::dt(HTML::em(WikiLink($pagename))), $mesg);
491 PrintXML(HTML::dt(WikiLink($pagename)), $mesg);
495 function _tryinsertInterWikiMap($content) {
497 if (strpos($content, "<verbatim>")) {
498 //$error_html = " The newly loaded pgsrc already contains a verbatim block.";
501 if (!$goback && !defined('INTERWIKI_MAP_FILE')) {
502 $error_html = sprintf(" "._("%s: not defined"), "INTERWIKI_MAP_FILE");
505 if (!$goback && !file_exists(INTERWIKI_MAP_FILE)) {
506 $error_html = sprintf(" "._("%s: file not found"), INTERWIKI_MAP_FILE);
510 if (!empty($error_html))
511 trigger_error(_("Default InterWiki map file not loaded.")
512 . $error_html, E_USER_NOTICE);
517 $filename = INTERWIKI_MAP_FILE;
518 trigger_error(sprintf(_("Loading InterWikiMap from external file %s."),
519 $filename), E_USER_NOTICE);
521 $fd = fopen ($filename, "rb");
522 $data = fread ($fd, filesize($filename));
524 $content = $content . "\n<verbatim>\n$data</verbatim>\n";
528 function ParseSerializedPage($text, $default_pagename, $user)
530 if (!preg_match('/^a:\d+:{[si]:\d+/', $text))
533 $pagehash = unserialize($text);
535 // Split up pagehash into four parts:
538 // page-level meta-data
539 // revision-level meta-data
541 if (!defined('FLAG_PAGE_LOCKED'))
542 define('FLAG_PAGE_LOCKED', 1);
543 $pageinfo = array('pagedata' => array(),
544 'versiondata' => array());
546 $pagedata = &$pageinfo['pagedata'];
547 $versiondata = &$pageinfo['versiondata'];
550 if (empty($pagehash['pagename']))
551 $pagehash['pagename'] = $default_pagename;
552 if (empty($pagehash['author'])) {
553 $pagehash['author'] = $user->getId();
556 foreach ($pagehash as $key => $value) {
561 $pageinfo[$key] = $value;
564 $pageinfo[$key] = join("\n", $value);
567 if (($value & FLAG_PAGE_LOCKED) != 0)
568 $pagedata['locked'] = 'yes';
571 $pagedata[$key] = $value;
574 $versiondata['mtime'] = $value;
579 $versiondata[$key] = $value;
586 function SortByPageVersion ($a, $b) {
587 return $a['version'] - $b['version'];
590 function LoadFile (&$request, $filename, $text = false, $mtime = false)
592 if (!is_string($text)) {
594 $stat = stat($filename);
596 $text = implode("", file($filename));
599 @set_time_limit(30); // Reset watchdog.
601 // FIXME: basename("filewithnoslashes") seems to return garbage sometimes.
602 $basename = basename("/dummy/" . $filename);
605 $mtime = time(); // Last resort.
607 $default_pagename = rawurldecode($basename);
609 if ( ($parts = ParseMimeifiedPages($text)) ) {
610 usort($parts, 'SortByPageVersion');
611 foreach ($parts as $pageinfo)
612 SavePage($request, $pageinfo, sprintf(_("MIME file %s"),
613 $filename), $basename);
615 else if ( ($pageinfo = ParseSerializedPage($text, $default_pagename,
616 $request->getUser())) ) {
617 SavePage($request, $pageinfo, sprintf(_("Serialized file %s"),
618 $filename), $basename);
621 $user = $request->getUser();
623 // Assume plain text file.
624 $pageinfo = array('pagename' => $default_pagename,
625 'pagedata' => array(),
627 => array('author' => $user->getId()),
628 'content' => preg_replace('/[ \t\r]*\n/', "\n",
631 SavePage($request, $pageinfo, sprintf(_("plain file %s"), $filename),
636 function LoadZip (&$request, $zipfile, $files = false, $exclude = false) {
637 $zip = new ZipReader($zipfile);
638 while (list ($fn, $data, $attrib) = $zip->readFile()) {
639 // FIXME: basename("filewithnoslashes") seems to return
640 // garbage sometimes.
641 $fn = basename("/dummy/" . $fn);
642 if ( ($files && !in_array($fn, $files))
643 || ($exclude && in_array($fn, $exclude)) ) {
644 PrintXML(HTML::dt(WikiLink($fn)),
645 HTML::dd(_("Skipping")));
649 LoadFile($request, $fn, $data, $attrib['mtime']);
653 function LoadDir (&$request, $dirname, $files = false, $exclude = false) {
654 $fileset = new LimitedFileSet($dirname, $files, $exclude);
656 if (($skiplist = $fileset->getSkippedFiles())) {
657 PrintXML(HTML::dt(HTML::strong(_("Skipping"))));
659 foreach ($skiplist as $file)
660 $list->pushContent(HTML::li(WikiLink($file)));
661 PrintXML(HTML::dd($list));
664 // Defer HomePage loading until the end. If anything goes wrong
665 // the pages can still be loaded again.
666 $files = $fileset->getFiles();
667 if (in_array(HOME_PAGE, $files)) {
668 $files = array_diff($files, array(HOME_PAGE));
669 $files[] = HOME_PAGE;
671 foreach ($files as $file)
672 LoadFile($request, "$dirname/$file");
675 class LimitedFileSet extends FileSet {
676 function LimitedFileSet($dirname, $_include, $exclude) {
677 $this->_includefiles = $_include;
678 $this->_exclude = $exclude;
679 $this->_skiplist = array();
680 parent::FileSet($dirname);
683 function _filenameSelector($fn) {
684 $incl = &$this->_includefiles;
685 $excl = &$this->_exclude;
687 if ( ($incl && !in_array($fn, $incl))
688 || ($excl && in_array($fn, $excl)) ) {
689 $this->_skiplist[] = $fn;
696 function getSkippedFiles () {
697 return $this->_skiplist;
702 function IsZipFile ($filename_or_fd)
704 // See if it looks like zip file
705 if (is_string($filename_or_fd))
707 $fd = fopen($filename_or_fd, "rb");
708 $magic = fread($fd, 4);
713 $fpos = ftell($filename_or_fd);
714 $magic = fread($filename_or_fd, 4);
715 fseek($filename_or_fd, $fpos);
718 return $magic == ZIP_LOCHEAD_MAGIC || $magic == ZIP_CENTHEAD_MAGIC;
722 function LoadAny (&$request, $file_or_dir, $files = false, $exclude = false)
724 // Try urlencoded filename for accented characters.
725 if (!file_exists($file_or_dir)) {
726 // Make sure there are slashes first to avoid confusing phps
727 // with broken dirname or basename functions.
728 // FIXME: windows uses \ and :
729 if (is_integer(strpos($file_or_dir, "/"))) {
730 $file_or_dir = FindFile($file_or_dir);
732 if (!file_exists($file_or_dir))
733 $file_or_dir = dirname($file_or_dir) . "/"
734 . urlencode(basename($file_or_dir));
736 // This is probably just a file.
737 $file_or_dir = urlencode($file_or_dir);
741 $type = filetype($file_or_dir);
742 if ($type == 'link') {
743 // For symbolic links, use stat() to determine
744 // the type of the underlying file.
745 list(,,$mode) = stat($file_or_dir);
746 $type = ($mode >> 12) & 017;
749 elseif ($type == 004)
754 $request->finish(fmt("Unable to load: %s", $file_or_dir));
756 else if ($type == 'dir') {
757 LoadDir($request, $file_or_dir, $files, $exclude);
759 else if ($type != 'file' && !preg_match('/^(http|ftp):/', $file_or_dir))
761 $request->finish(fmt("Bad file type: %s", $type));
763 else if (IsZipFile($file_or_dir)) {
764 LoadZip($request, $file_or_dir, $files, $exclude);
766 else /* if (!$files || in_array(basename($file_or_dir), $files)) */
768 LoadFile($request, $file_or_dir);
772 function LoadFileOrDir (&$request)
774 $source = $request->getArg('source');
775 StartLoadDump($request, fmt("Loading '%s'", HTML(dirname($source),
777 WikiLink(basename($source),
780 LoadAny($request, $source);
782 EndLoadDump($request);
785 function SetupWiki (&$request)
787 global $GenericPages, $LANG;
790 //FIXME: This is a hack (err, "interim solution")
791 // This is a bogo-bogo-login: Login without
792 // saving login information in session state.
793 // This avoids logging in the unsuspecting
794 // visitor as "The PhpWiki programming team".
796 // This really needs to be cleaned up...
797 // (I'm working on it.)
798 $real_user = $request->_user;
800 $request->_user = new _BogoUser(_("The PhpWiki programming team"));
803 $request->_user = new WikiUser($request, _("The PhpWiki programming team"),
806 StartLoadDump($request, _("Loading up virgin wiki"));
809 $pgsrc = FindLocalizedFile(WIKI_PGSRC);
810 $default_pgsrc = FindFile(DEFAULT_WIKI_PGSRC);
812 if ($default_pgsrc != $pgsrc)
813 LoadAny($request, $default_pgsrc, $GenericPages);
815 LoadAny($request, $pgsrc);
818 EndLoadDump($request);
821 function LoadPostFile (&$request)
823 $upload = $request->getUploadedFile('file');
826 $request->finish(_("No uploaded file to upload?")); // FIXME: more concise message
829 // Dump http headers.
830 StartLoadDump($request, sprintf(_("Uploading %s"), $upload->getName()));
833 $fd = $upload->open();
835 LoadZip($request, $fd, false, array(_("RecentChanges")));
837 LoadFile($request, $upload->getName(), $upload->getContents());
840 EndLoadDump($request);
844 $Log: not supported by cvs2svn $
845 Revision 1.87 2004/01/26 09:17:49 rurban
846 * changed stored pref representation as before.
847 the array of objects is 1) bigger and 2)
848 less portable. If we would import packed pref
849 objects and the object definition was changed, PHP would fail.
850 This doesn't happen with an simple array of non-default values.
851 * use $prefs->retrieve and $prefs->store methods, where retrieve
852 understands the interim format of array of objects also.
853 * simplified $prefs->get() and fixed $prefs->set()
854 * added $user->_userid and class '_WikiUser' portability functions
855 * fixed $user object ->_level upgrading, mostly using sessions.
856 this fixes yesterdays problems with loosing authorization level.
857 * fixed WikiUserNew::checkPass to return the _level
858 * fixed WikiUserNew::isSignedIn
859 * added explodePageList to class PageList, support sortby arg
860 * fixed UserPreferences for WikiUserNew
861 * fixed WikiPlugin for empty defaults array
862 * UnfoldSubpages: added pagename arg, renamed pages arg,
863 removed sort arg, support sortby arg
865 Revision 1.86 2003/12/02 16:18:26 carstenklapp
866 Minor enhancement: Provide more meaningful filenames for WikiDB zip
869 Revision 1.85 2003/11/30 18:18:13 carstenklapp
870 Minor code optimization: use include_once instead of require_once
871 inside functions that might not always called.
873 Revision 1.84 2003/11/26 20:47:47 carstenklapp
874 Redo bugfix: My last refactoring broke merge-edit & overwrite
875 functionality again, should be fixed now. Sorry.
877 Revision 1.83 2003/11/20 22:18:54 carstenklapp
878 New feature: h1 during merge-edit displays WikiLink to original page.
879 Internal changes: Replaced some hackish url-generation code in
880 function SavePage (for pgsrc merge-edit) with appropriate Button()
883 Revision 1.82 2003/11/18 19:48:01 carstenklapp
884 Fixed missing gettext _() for button name.
886 Revision 1.81 2003/11/18 18:28:35 carstenklapp
887 Bugfix: In the Load File function of PhpWikiAdministration: When doing
888 a "Merge Edit" or "Restore Anyway", page names containing accented
889 letters (such as locale/de/pgsrc/G%E4steBuch) would produce a file not
890 found error (Use FilenameForPage funtion to urlencode page names).
892 Revision 1.80 2003/03/07 02:46:57 dairiki
893 Omit checks for safe_mode before set_time_limit(). Just prefix the
894 set_time_limit() calls with @ so that they fail silently if not
897 Revision 1.79 2003/02/26 01:56:05 dairiki
898 Only zip pages with legal pagenames.
900 Revision 1.78 2003/02/24 02:05:43 dairiki
901 Fix "n bytes written" message when dumping HTML.
903 Revision 1.77 2003/02/21 04:12:05 dairiki
904 Minor fixes for new cached markup.
906 Revision 1.76 2003/02/16 19:47:17 dairiki
907 Update WikiDB timestamp when editing or deleting pages.
909 Revision 1.75 2003/02/15 03:04:30 dairiki
910 Fix for WikiUser constructor API change.
912 Revision 1.74 2003/02/15 02:18:04 dairiki
913 When default language was English (at least), pgsrc was being
916 LimitedFileSet: Fix typo/bug. ($include was being ignored.)
918 SetupWiki(): Fix bugs in loading of $GenericPages.
920 Revision 1.73 2003/01/28 21:09:17 zorloc
921 The get_cfg_var() function should only be used when one is
922 interested in the value from php.ini or similar. Use ini_get()
923 instead to get the effective value of a configuration variable.
926 Revision 1.72 2003/01/03 22:25:53 carstenklapp
927 Cosmetic fix to "Merge Edit" & "Overwrite" buttons. Added "The PhpWiki
928 programming team" as author when loading from pgsrc. Source
931 Revision 1.71 2003/01/03 02:48:05 carstenklapp
932 function SavePage: Added loadfile options for overwriting or merge &
933 compare a loaded pgsrc file with an existing page.
935 function LoadAny: Added a general error message when unable to load a
936 file instead of defaulting to "Bad file type".
945 // c-hanging-comment-ender-p: nil
946 // indent-tabs-mode: nil