2 rcs_id('$Id: loadsave.php,v 1.90 2004-02-24 17:09:24 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 if (! $request->getArg('start_debug'))
194 @set_time_limit(30); // Reset watchdog.
196 $filename = FilenameForPage($page->getName());
198 $msg = HTML(HTML::br(), $page->getName(), ' ... ');
200 if($page->getName() != $filename) {
201 $msg->pushContent(HTML::small(fmt("saved as %s", $filename)),
205 if ($request->getArg('include') == 'all')
206 $data = MailifyPage($page, 0);
208 $data = MailifyPage($page);
210 if ( !($fd = fopen("$directory/$filename", "wb")) ) {
211 $msg->pushContent(HTML::strong(fmt("couldn't open file '%s' for writing",
212 "$directory/$filename")));
213 $request->finish($msg);
216 $num = fwrite($fd, $data, strlen($data));
217 $msg->pushContent(HTML::small(fmt("%s bytes written", $num)));
221 assert($num == strlen($data));
225 EndLoadDump($request);
229 function DumpHtmlToDir (&$request)
231 $directory = $request->getArg('directory');
232 if (empty($directory))
233 $request->finish(_("You must specify a directory to dump to"));
235 // see if we can access the directory the user wants us to use
236 if (! file_exists($directory)) {
237 if (! mkdir($directory, 0755))
238 $request->finish(fmt("Cannot create directory '%s'", $directory));
240 $html = HTML::p(fmt("Created directory '%s' for the page dump...",
243 $html = HTML::p(fmt("Using directory '%s'", $directory));
246 StartLoadDump($request, _("Dumping Pages"), $html);
247 $thispage = $request->getArg('pagename'); // for "Return to ..."
249 $dbi = $request->getDbh();
250 $pages = $dbi->getAllPages();
252 global $HTML_DUMP_SUFFIX, $Theme;
253 if ($HTML_DUMP_SUFFIX)
254 $Theme->HTML_DUMP_SUFFIX = $HTML_DUMP_SUFFIX;
256 while ($page = $pages->next()) {
257 if (! $request->getArg('start_debug'))
258 @set_time_limit(30); // Reset watchdog.
260 $pagename = $page->getName();
261 $request->setArg('pagename',$pagename); // Template::_basepage fix
262 $filename = FilenameForPage($pagename) . $Theme->HTML_DUMP_SUFFIX;
264 $msg = HTML(HTML::br(), $pagename, ' ... ');
266 if($page->getName() != $filename) {
267 $msg->pushContent(HTML::small(fmt("saved as %s", $filename)),
271 $revision = $page->getCurrentRevision();
272 $transformedContent = $revision->getTransformedContent();
273 $template = new Template('browse', $request,
274 array('revision' => $revision,
275 'CONTENT' => $transformedContent));
277 $data = GeneratePageasXML($template, $pagename);
279 if ( !($fd = fopen("$directory/$filename", "wb")) ) {
280 $msg->pushContent(HTML::strong(fmt("couldn't open file '%s' for writing",
281 "$directory/$filename")));
282 $request->finish($msg);
285 $num = fwrite($fd, $data, strlen($data));
286 $msg->pushContent(HTML::small(fmt("%s bytes written", $num), "\n"));
290 assert($num == strlen($data));
294 //CopyImageFiles() will go here;
295 $Theme->$HTML_DUMP_SUFFIX = '';
297 $request->setArg('pagename',$thispage); // Template::_basepage fix
298 EndLoadDump($request);
301 /* Known problem: any plugins or other code which echo()s text will
302 * lead to a corrupted html zip file which may produce the following
303 * errors upon unzipping:
305 * warning [wikihtml.zip]: 2401 extra bytes at beginning or within zipfile
306 * file #58: bad zipfile offset (local header sig): 177561
307 * (attempting to re-compensate)
309 * However, the actual wiki page data should be unaffected.
311 function MakeWikiZipHtml (&$request)
313 $zipname = "wikihtml.zip";
314 $zip = new ZipWriter("Created by PhpWiki " . PHPWIKI_VERSION, $zipname);
315 $dbi = $request->getDbh();
316 $pages = $dbi->getAllPages();
318 global $HTML_DUMP_SUFFIX, $Theme;
319 if ($HTML_DUMP_SUFFIX)
320 $Theme->HTML_DUMP_SUFFIX = $HTML_DUMP_SUFFIX;
322 while ($page = $pages->next()) {
323 @set_time_limit(30); // Reset watchdog.
325 $current = $page->getCurrentRevision();
326 if ($current->getVersion() == 0)
329 $attrib = array('mtime' => $current->get('mtime'),
331 if ($page->get('locked'))
332 $attrib['write_protected'] = 1;
334 $pagename = $page->getName();
335 $request->setArg('pagename',$pagename); // Template::_basepage fix
336 $filename = FilenameForPage($pagename) . $Theme->HTML_DUMP_SUFFIX;
337 $revision = $page->getCurrentRevision();
339 $transformedContent = $revision->getTransformedContent();
341 $template = new Template('browse', $request,
342 array('revision' => $revision,
343 'CONTENT' => $transformedContent));
345 $data = GeneratePageasXML($template, $pagename);
347 $zip->addRegularFile( $filename, $data, $attrib);
349 // FIXME: Deal with images here.
351 $Theme->$HTML_DUMP_SUFFIX = '';
355 ////////////////////////////////////////////////////////////////
357 // Functions for restoring.
359 ////////////////////////////////////////////////////////////////
361 function SavePage (&$request, $pageinfo, $source, $filename)
363 $pagedata = $pageinfo['pagedata']; // Page level meta-data.
364 $versiondata = $pageinfo['versiondata']; // Revision level meta-data.
366 if (empty($pageinfo['pagename'])) {
367 PrintXML(HTML::dt(HTML::strong(_("Empty pagename!"))));
371 if (empty($versiondata['author_id']))
372 $versiondata['author_id'] = $versiondata['author'];
374 $pagename = $pageinfo['pagename'];
375 $content = $pageinfo['content'];
377 if ($pagename ==_("InterWikiMap"))
378 $content = _tryinsertInterWikiMap($content);
380 $dbi = $request->getDbh();
381 $page = $dbi->getPage($pagename);
383 $current = $page->getCurrentRevision();
384 // Try to merge if updated pgsrc contents are different. This
385 // whole thing is hackish
387 // TODO: try merge unless:
388 // if (current contents = default contents && pgsrc_version >=
389 // pgsrc_version) then just upgrade this pgsrc
390 $needs_merge = false;
394 if ($request->getArg('merge')) {
397 else if ($request->getArg('overwrite')) {
401 if ( (! $current->hasDefaultContents())
402 && ($current->getPackedContent() != $content)
403 && ($merging == true) ) {
404 include_once('lib/editpage.php');
405 $request->setArg('pagename', $pagename);
406 $r = $current->getVersion();
407 $request->setArg('revision', $current->getVersion());
408 $p = new LoadFileConflictPageEditor($request);
409 $p->_content = $content;
410 $p->_currentVersion = $r - 1;
411 $p->editPage($saveFailed = true);
412 return; //early return
415 foreach ($pagedata as $key => $value) {
417 $page->set($key, $value);
423 $mesg->pushContent(' ', fmt("from %s", $source));
426 $current = $page->getCurrentRevision();
427 if ($current->getVersion() == 0) {
428 $mesg->pushContent(' ', _("new page"));
432 if ( (! $current->hasDefaultContents())
433 && ($current->getPackedContent() != $content) ) {
435 $mesg->pushContent(' ',
436 fmt("has edit conflicts - overwriting anyway"));
438 if (substr_count($source, 'pgsrc')) {
439 $versiondata['author'] = _("The PhpWiki programming team");
440 // but leave authorid as userid who loaded the file
444 $mesg->pushContent(' ', fmt("has edit conflicts - skipped"));
445 $needs_merge = true; // hackish
449 else if ($current->getPackedContent() == $content
450 && $current->get('author') == $versiondata['author']) {
451 $mesg->pushContent(' ',
452 fmt("is identical to current version %d - skipped",
453 $current->getVersion()));
460 $new = $page->save($content, WIKIDB_FORCE_CREATE, $versiondata);
462 $mesg->pushContent(' ', fmt("- saved to database as version %d",
463 $new->getVersion()));
467 // hackish, $source contains needed path+filename
468 $f = str_replace(sprintf(_("MIME file %s"), ''), '', $f);
469 $f = str_replace(sprintf(_("Serialized file %s"), ''), '', $f);
470 $f = str_replace(sprintf(_("plain file %s"), ''), '', $f);
471 //check if uploaded file? they pass just the content, but the file is gone
474 $meb = Button(array('action' => 'loadfile',
478 _("PhpWikiAdministration"),
480 $owb = Button(array('action' => 'loadfile',
484 _("PhpWikiAdministration"),
487 $mesg->pushContent(' ', $meb, " ", $owb);
491 PrintXML(HTML::dt(HTML::em(WikiLink($pagename))), $mesg);
493 PrintXML(HTML::dt(WikiLink($pagename)), $mesg);
497 function _tryinsertInterWikiMap($content) {
499 if (strpos($content, "<verbatim>")) {
500 //$error_html = " The newly loaded pgsrc already contains a verbatim block.";
503 if (!$goback && !defined('INTERWIKI_MAP_FILE')) {
504 $error_html = sprintf(" "._("%s: not defined"), "INTERWIKI_MAP_FILE");
507 if (!$goback && !file_exists(INTERWIKI_MAP_FILE)) {
508 $error_html = sprintf(" "._("%s: file not found"), INTERWIKI_MAP_FILE);
512 if (!empty($error_html))
513 trigger_error(_("Default InterWiki map file not loaded.")
514 . $error_html, E_USER_NOTICE);
519 $filename = INTERWIKI_MAP_FILE;
520 trigger_error(sprintf(_("Loading InterWikiMap from external file %s."),
521 $filename), E_USER_NOTICE);
523 $fd = fopen ($filename, "rb");
524 $data = fread ($fd, filesize($filename));
526 $content = $content . "\n<verbatim>\n$data</verbatim>\n";
530 function ParseSerializedPage($text, $default_pagename, $user)
532 if (!preg_match('/^a:\d+:{[si]:\d+/', $text))
535 $pagehash = unserialize($text);
537 // Split up pagehash into four parts:
540 // page-level meta-data
541 // revision-level meta-data
543 if (!defined('FLAG_PAGE_LOCKED'))
544 define('FLAG_PAGE_LOCKED', 1);
545 $pageinfo = array('pagedata' => array(),
546 'versiondata' => array());
548 $pagedata = &$pageinfo['pagedata'];
549 $versiondata = &$pageinfo['versiondata'];
552 if (empty($pagehash['pagename']))
553 $pagehash['pagename'] = $default_pagename;
554 if (empty($pagehash['author'])) {
555 $pagehash['author'] = $user->getId();
558 foreach ($pagehash as $key => $value) {
563 $pageinfo[$key] = $value;
566 $pageinfo[$key] = join("\n", $value);
569 if (($value & FLAG_PAGE_LOCKED) != 0)
570 $pagedata['locked'] = 'yes';
573 $pagedata[$key] = $value;
576 $versiondata['mtime'] = $value;
581 $versiondata[$key] = $value;
588 function SortByPageVersion ($a, $b) {
589 return $a['version'] - $b['version'];
592 function LoadFile (&$request, $filename, $text = false, $mtime = false)
594 if (!is_string($text)) {
596 $stat = stat($filename);
598 $text = implode("", file($filename));
601 @set_time_limit(30); // Reset watchdog.
603 // FIXME: basename("filewithnoslashes") seems to return garbage sometimes.
604 $basename = basename("/dummy/" . $filename);
607 $mtime = time(); // Last resort.
609 $default_pagename = rawurldecode($basename);
611 if ( ($parts = ParseMimeifiedPages($text)) ) {
612 usort($parts, 'SortByPageVersion');
613 foreach ($parts as $pageinfo)
614 SavePage($request, $pageinfo, sprintf(_("MIME file %s"),
615 $filename), $basename);
617 else if ( ($pageinfo = ParseSerializedPage($text, $default_pagename,
618 $request->getUser())) ) {
619 SavePage($request, $pageinfo, sprintf(_("Serialized file %s"),
620 $filename), $basename);
623 $user = $request->getUser();
625 // Assume plain text file.
626 $pageinfo = array('pagename' => $default_pagename,
627 'pagedata' => array(),
629 => array('author' => $user->getId()),
630 'content' => preg_replace('/[ \t\r]*\n/', "\n",
633 SavePage($request, $pageinfo, sprintf(_("plain file %s"), $filename),
638 function LoadZip (&$request, $zipfile, $files = false, $exclude = false) {
639 $zip = new ZipReader($zipfile);
640 while (list ($fn, $data, $attrib) = $zip->readFile()) {
641 // FIXME: basename("filewithnoslashes") seems to return
642 // garbage sometimes.
643 $fn = basename("/dummy/" . $fn);
644 if ( ($files && !in_array($fn, $files))
645 || ($exclude && in_array($fn, $exclude)) ) {
646 PrintXML(HTML::dt(WikiLink($fn)),
647 HTML::dd(_("Skipping")));
651 LoadFile($request, $fn, $data, $attrib['mtime']);
655 function LoadDir (&$request, $dirname, $files = false, $exclude = false) {
656 $fileset = new LimitedFileSet($dirname, $files, $exclude);
658 if (($skiplist = $fileset->getSkippedFiles())) {
659 PrintXML(HTML::dt(HTML::strong(_("Skipping"))));
661 foreach ($skiplist as $file)
662 $list->pushContent(HTML::li(WikiLink($file)));
663 PrintXML(HTML::dd($list));
666 // Defer HomePage loading until the end. If anything goes wrong
667 // the pages can still be loaded again.
668 $files = $fileset->getFiles();
669 if (in_array(HOME_PAGE, $files)) {
670 $files = array_diff($files, array(HOME_PAGE));
671 $files[] = HOME_PAGE;
673 foreach ($files as $file)
674 LoadFile($request, "$dirname/$file");
677 class LimitedFileSet extends FileSet {
678 function LimitedFileSet($dirname, $_include, $exclude) {
679 $this->_includefiles = $_include;
680 $this->_exclude = $exclude;
681 $this->_skiplist = array();
682 parent::FileSet($dirname);
685 function _filenameSelector($fn) {
686 $incl = &$this->_includefiles;
687 $excl = &$this->_exclude;
689 if ( ($incl && !in_array($fn, $incl))
690 || ($excl && in_array($fn, $excl)) ) {
691 $this->_skiplist[] = $fn;
698 function getSkippedFiles () {
699 return $this->_skiplist;
704 function IsZipFile ($filename_or_fd)
706 // See if it looks like zip file
707 if (is_string($filename_or_fd))
709 $fd = fopen($filename_or_fd, "rb");
710 $magic = fread($fd, 4);
715 $fpos = ftell($filename_or_fd);
716 $magic = fread($filename_or_fd, 4);
717 fseek($filename_or_fd, $fpos);
720 return $magic == ZIP_LOCHEAD_MAGIC || $magic == ZIP_CENTHEAD_MAGIC;
724 function LoadAny (&$request, $file_or_dir, $files = false, $exclude = false)
726 // Try urlencoded filename for accented characters.
727 if (!file_exists($file_or_dir)) {
728 // Make sure there are slashes first to avoid confusing phps
729 // with broken dirname or basename functions.
730 // FIXME: windows uses \ and :
731 if (is_integer(strpos($file_or_dir, "/"))) {
732 $file_or_dir = FindFile($file_or_dir);
734 if (!file_exists($file_or_dir))
735 $file_or_dir = dirname($file_or_dir) . "/"
736 . urlencode(basename($file_or_dir));
738 // This is probably just a file.
739 $file_or_dir = urlencode($file_or_dir);
743 $type = filetype($file_or_dir);
744 if ($type == 'link') {
745 // For symbolic links, use stat() to determine
746 // the type of the underlying file.
747 list(,,$mode) = stat($file_or_dir);
748 $type = ($mode >> 12) & 017;
751 elseif ($type == 004)
756 $request->finish(fmt("Unable to load: %s", $file_or_dir));
758 else if ($type == 'dir') {
759 LoadDir($request, $file_or_dir, $files, $exclude);
761 else if ($type != 'file' && !preg_match('/^(http|ftp):/', $file_or_dir))
763 $request->finish(fmt("Bad file type: %s", $type));
765 else if (IsZipFile($file_or_dir)) {
766 LoadZip($request, $file_or_dir, $files, $exclude);
768 else /* if (!$files || in_array(basename($file_or_dir), $files)) */
770 LoadFile($request, $file_or_dir);
774 function LoadFileOrDir (&$request)
776 $source = $request->getArg('source');
777 StartLoadDump($request, fmt("Loading '%s'", HTML(dirname($source),
779 WikiLink(basename($source),
782 LoadAny($request, $source);
784 EndLoadDump($request);
787 function SetupWiki (&$request)
789 global $GenericPages, $LANG;
792 //FIXME: This is a hack (err, "interim solution")
793 // This is a bogo-bogo-login: Login without
794 // saving login information in session state.
795 // This avoids logging in the unsuspecting
796 // visitor as "The PhpWiki programming team".
798 // This really needs to be cleaned up...
799 // (I'm working on it.)
800 $real_user = $request->_user;
802 $request->_user = new _BogoUser(_("The PhpWiki programming team"));
805 $request->_user = new WikiUser($request, _("The PhpWiki programming team"),
808 StartLoadDump($request, _("Loading up virgin wiki"));
811 $pgsrc = FindLocalizedFile(WIKI_PGSRC);
812 $default_pgsrc = FindFile(DEFAULT_WIKI_PGSRC);
814 if ($default_pgsrc != $pgsrc)
815 LoadAny($request, $default_pgsrc, $GenericPages);
817 LoadAny($request, $pgsrc);
820 EndLoadDump($request);
823 function LoadPostFile (&$request)
825 $upload = $request->getUploadedFile('file');
828 $request->finish(_("No uploaded file to upload?")); // FIXME: more concise message
831 // Dump http headers.
832 StartLoadDump($request, sprintf(_("Uploading %s"), $upload->getName()));
835 $fd = $upload->open();
837 LoadZip($request, $fd, false, array(_("RecentChanges")));
839 LoadFile($request, $upload->getName(), $upload->getContents());
842 EndLoadDump($request);
846 $Log: not supported by cvs2svn $
847 Revision 1.88 2004/02/22 23:20:31 rurban
849 enhanced sortby handling in PageList
850 new button_heading th style (enabled),
851 added sortby and limit support to the db backends and plugins
852 for paging support (<<prev, next>> links on long lists)
854 Revision 1.87 2004/01/26 09:17:49 rurban
855 * changed stored pref representation as before.
856 the array of objects is 1) bigger and 2)
857 less portable. If we would import packed pref
858 objects and the object definition was changed, PHP would fail.
859 This doesn't happen with an simple array of non-default values.
860 * use $prefs->retrieve and $prefs->store methods, where retrieve
861 understands the interim format of array of objects also.
862 * simplified $prefs->get() and fixed $prefs->set()
863 * added $user->_userid and class '_WikiUser' portability functions
864 * fixed $user object ->_level upgrading, mostly using sessions.
865 this fixes yesterdays problems with loosing authorization level.
866 * fixed WikiUserNew::checkPass to return the _level
867 * fixed WikiUserNew::isSignedIn
868 * added explodePageList to class PageList, support sortby arg
869 * fixed UserPreferences for WikiUserNew
870 * fixed WikiPlugin for empty defaults array
871 * UnfoldSubpages: added pagename arg, renamed pages arg,
872 removed sort arg, support sortby arg
874 Revision 1.86 2003/12/02 16:18:26 carstenklapp
875 Minor enhancement: Provide more meaningful filenames for WikiDB zip
878 Revision 1.85 2003/11/30 18:18:13 carstenklapp
879 Minor code optimization: use include_once instead of require_once
880 inside functions that might not always called.
882 Revision 1.84 2003/11/26 20:47:47 carstenklapp
883 Redo bugfix: My last refactoring broke merge-edit & overwrite
884 functionality again, should be fixed now. Sorry.
886 Revision 1.83 2003/11/20 22:18:54 carstenklapp
887 New feature: h1 during merge-edit displays WikiLink to original page.
888 Internal changes: Replaced some hackish url-generation code in
889 function SavePage (for pgsrc merge-edit) with appropriate Button()
892 Revision 1.82 2003/11/18 19:48:01 carstenklapp
893 Fixed missing gettext _() for button name.
895 Revision 1.81 2003/11/18 18:28:35 carstenklapp
896 Bugfix: In the Load File function of PhpWikiAdministration: When doing
897 a "Merge Edit" or "Restore Anyway", page names containing accented
898 letters (such as locale/de/pgsrc/G%E4steBuch) would produce a file not
899 found error (Use FilenameForPage funtion to urlencode page names).
901 Revision 1.80 2003/03/07 02:46:57 dairiki
902 Omit checks for safe_mode before set_time_limit(). Just prefix the
903 set_time_limit() calls with @ so that they fail silently if not
906 Revision 1.79 2003/02/26 01:56:05 dairiki
907 Only zip pages with legal pagenames.
909 Revision 1.78 2003/02/24 02:05:43 dairiki
910 Fix "n bytes written" message when dumping HTML.
912 Revision 1.77 2003/02/21 04:12:05 dairiki
913 Minor fixes for new cached markup.
915 Revision 1.76 2003/02/16 19:47:17 dairiki
916 Update WikiDB timestamp when editing or deleting pages.
918 Revision 1.75 2003/02/15 03:04:30 dairiki
919 Fix for WikiUser constructor API change.
921 Revision 1.74 2003/02/15 02:18:04 dairiki
922 When default language was English (at least), pgsrc was being
925 LimitedFileSet: Fix typo/bug. ($include was being ignored.)
927 SetupWiki(): Fix bugs in loading of $GenericPages.
929 Revision 1.73 2003/01/28 21:09:17 zorloc
930 The get_cfg_var() function should only be used when one is
931 interested in the value from php.ini or similar. Use ini_get()
932 instead to get the effective value of a configuration variable.
935 Revision 1.72 2003/01/03 22:25:53 carstenklapp
936 Cosmetic fix to "Merge Edit" & "Overwrite" buttons. Added "The PhpWiki
937 programming team" as author when loading from pgsrc. Source
940 Revision 1.71 2003/01/03 02:48:05 carstenklapp
941 function SavePage: Added loadfile options for overwriting or merge &
942 compare a loaded pgsrc file with an existing page.
944 function LoadAny: Added a general error message when unable to load a
945 file instead of defaulting to "Bad file type".
954 // c-hanging-comment-ender-p: nil
955 // indent-tabs-mode: nil