2 rcs_id('$Id: loadsave.php,v 1.107 2004-06-14 11:31:37 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");
29 * ignore fatal errors during dump
31 function _ignore_fatal_plugin_error_handler(&$error) {
32 if ($error->isFatal()) {
33 $error->errno = E_USER_WARNING;
36 return false; // let the message come through: call the remaining handlers:
38 if (preg_match('/Plugin/',$error->errstr))
39 return true; // Ignore error
43 function StartLoadDump(&$request, $title, $html = '')
45 // FIXME: This is a hack
46 $tmpl = Template('html', array('TITLE' => $title,
48 'CONTENT' => '%BODY%'));
49 echo ereg_replace('%BODY%.*', '', $tmpl->getExpansion($html));
51 /* ignore fatals in plugins */
53 $ErrorManager->pushErrorHandler(new WikiFunctionCb('_ignore_fatal_plugin_error_handler'));
56 function EndLoadDump(&$request)
59 $ErrorManager->popErrorHandler();
60 // FIXME: This is a hack
61 $pagelink = WikiLink($request->getPage());
63 PrintXML(HTML::p(HTML::strong(_("Complete."))),
64 HTML::p(fmt("Return to %s", $pagelink)));
65 echo "</body></html>\n";
69 ////////////////////////////////////////////////////////////////
71 // Functions for dumping.
73 ////////////////////////////////////////////////////////////////
77 * http://www.nacs.uci.edu/indiv/ehood/MIME/2045/rfc2045.html
78 * http://www.faqs.org/rfcs/rfc2045.html
79 * (RFC 1521 has been superceeded by RFC 2045 & others).
81 * Also see http://www.faqs.org/rfcs/rfc2822.html
83 function MailifyPage ($page, $nversions = 1)
85 $current = $page->getCurrentRevision();
88 if (STRICT_MAILABLE_PAGEDUMPS) {
89 $from = defined('SERVER_ADMIN') ? SERVER_ADMIN : 'foo@bar';
90 //This is for unix mailbox format: (not RFC (2)822)
91 // $head .= "From $from " . CTime(time()) . "\r\n";
92 $head .= "Subject: " . rawurlencode($page->getName()) . "\r\n";
93 $head .= "From: $from (PhpWiki)\r\n";
94 // RFC 2822 requires only a Date: and originator (From:)
95 // field, however the obsolete standard RFC 822 also
96 // requires a destination field.
97 $head .= "To: $from (PhpWiki)\r\n";
99 $head .= "Date: " . Rfc2822DateTime($current->get('mtime')) . "\r\n";
100 $head .= sprintf("Mime-Version: 1.0 (Produced by PhpWiki %s)\r\n",
103 // This should just be entered by hand (or by script?)
104 // in the actual pgsrc files, since only they should have
106 //$head .= "X-Rcs-Id: \$Id\$\r\n";
108 $iter = $page->getAllRevisions();
110 while ($revision = $iter->next()) {
111 $parts[] = MimeifyPageRevision($revision);
112 if ($nversions > 0 && count($parts) >= $nversions)
115 if (count($parts) > 1)
116 return $head . MimeMultipart($parts);
118 return $head . $parts[0];
122 * Compute filename to used for storing contents of a wiki page.
124 * Basically we do a rawurlencode() which encodes everything except
125 * ASCII alphanumerics and '.', '-', and '_'.
127 * But we also want to encode leading dots to avoid filenames like
128 * '.', and '..'. (Also, there's no point in generating "hidden" file
129 * names, like '.foo'.)
131 * @param $pagename string Pagename.
132 * @return string Filename for page.
134 function FilenameForPage ($pagename)
136 $enc = rawurlencode($pagename);
137 return preg_replace('/^\./', '%2e', $enc);
141 * The main() function which generates a zip archive of a PhpWiki.
143 * If $include_archive is false, only the current version of each page
144 * is included in the zip file; otherwise all archived versions are
147 function MakeWikiZip (&$request)
149 if ($request->getArg('include') == 'all') {
150 $zipname = WIKI_NAME . _("FullDump") . date('Ymd-Hi') . '.zip';
151 $include_archive = true;
154 $zipname = WIKI_NAME . _("LatestSnapshot") . date('Ymd-Hi') . '.zip';
155 $include_archive = false;
159 $zip = new ZipWriter("Created by PhpWiki " . PHPWIKI_VERSION, $zipname);
161 /* ignore fatals in plugins */
162 global $ErrorManager;
163 $ErrorManager->pushErrorHandler(new WikiFunctionCb('_ignore_fatal_plugin_error_handler'));
165 $dbi = $request->getDbh();
166 $pages = $dbi->getAllPages();
167 while ($page = $pages->next()) {
168 if (! $request->getArg('start_debug'))
169 @set_time_limit(30); // Reset watchdog
171 $current = $page->getCurrentRevision();
172 if ($current->getVersion() == 0)
175 $wpn = new WikiPageName($page->getName());
176 if (!$wpn->isValid())
179 $attrib = array('mtime' => $current->get('mtime'),
181 if ($page->get('locked'))
182 $attrib['write_protected'] = 1;
184 if ($include_archive)
185 $content = MailifyPage($page, 0);
187 $content = MailifyPage($page);
189 $zip->addRegularFile( FilenameForPage($page->getName()),
193 $ErrorManager->popErrorHandler();
196 function DumpToDir (&$request)
198 $directory = $request->getArg('directory');
199 if (empty($directory))
200 $request->finish(_("You must specify a directory to dump to"));
202 // see if we can access the directory the user wants us to use
203 if (! file_exists($directory)) {
204 if (! mkdir($directory, 0755))
205 $request->finish(fmt("Cannot create directory '%s'", $directory));
207 $html = HTML::p(fmt("Created directory '%s' for the page dump...",
210 $html = HTML::p(fmt("Using directory '%s'", $directory));
213 StartLoadDump($request, _("Dumping Pages"), $html);
215 $dbi = $request->getDbh();
216 $pages = $dbi->getAllPages();
218 while ($page = $pages->next()) {
219 if (! $request->getArg('start_debug'))
220 @set_time_limit(30); // Reset watchdog.
222 $filename = FilenameForPage($page->getName());
224 $msg = HTML(HTML::br(), $page->getName(), ' ... ');
226 if($page->getName() != $filename) {
227 $msg->pushContent(HTML::small(fmt("saved as %s", $filename)),
231 if ($request->getArg('include') == 'all')
232 $data = MailifyPage($page, 0);
234 $data = MailifyPage($page);
236 if ( !($fd = fopen("$directory/$filename", "wb")) ) {
237 $msg->pushContent(HTML::strong(fmt("couldn't open file '%s' for writing",
238 "$directory/$filename")));
239 $request->finish($msg);
242 $num = fwrite($fd, $data, strlen($data));
243 $msg->pushContent(HTML::small(fmt("%s bytes written", $num)));
247 assert($num == strlen($data));
251 EndLoadDump($request);
255 function DumpHtmlToDir (&$request)
257 $directory = $request->getArg('directory');
258 if (empty($directory))
259 $request->finish(_("You must specify a directory to dump to"));
261 // see if we can access the directory the user wants us to use
262 if (! file_exists($directory)) {
263 if (! mkdir($directory, 0755))
264 $request->finish(fmt("Cannot create directory '%s'", $directory));
266 $html = HTML::p(fmt("Created directory '%s' for the page dump...",
269 $html = HTML::p(fmt("Using directory '%s'", $directory));
272 StartLoadDump($request, _("Dumping Pages"), $html);
273 $thispage = $request->getArg('pagename'); // for "Return to ..."
275 $dbi = $request->getDbh();
276 $pages = $dbi->getAllPages();
279 if (defined('HTML_DUMP_SUFFIX'))
280 $WikiTheme->HTML_DUMP_SUFFIX = HTML_DUMP_SUFFIX;
281 $WikiTheme->DUMP_MODE = 'HTML';
283 while ($page = $pages->next()) {
284 if (! $request->getArg('start_debug'))
285 @set_time_limit(30); // Reset watchdog.
287 $pagename = $page->getName();
288 $request->setArg('pagename',$pagename); // Template::_basepage fix
289 $filename = FilenameForPage($pagename) . $WikiTheme->HTML_DUMP_SUFFIX;
291 $msg = HTML(HTML::br(), $pagename, ' ... ');
293 $revision = $page->getCurrentRevision();
294 $transformedContent = $revision->getTransformedContent();
295 $template = new Template('browse', $request,
296 array('revision' => $revision,
297 'CONTENT' => $transformedContent));
299 $data = GeneratePageasXML($template, $pagename);
301 if ( !($fd = fopen("$directory/$filename", "wb")) ) {
302 $msg->pushContent(HTML::strong(fmt("couldn't open file '%s' for writing",
303 "$directory/$filename")));
304 $request->finish($msg);
306 $num = fwrite($fd, $data, strlen($data));
307 if($page->getName() != $filename) {
310 // drive where apache is installed
311 $prefix = '/' . substr($_SERVER["DOCUMENT_ROOT"],0,2);
313 $link = LinkURL("file://".$prefix.$directory."/".$filename,
315 $msg->pushContent(HTML::small(_("saved as "), $link, " ... "));
317 $msg->pushContent(HTML::small(fmt("%s bytes written", $num), "\n"));
321 assert($num == strlen($data));
325 if (is_array($WikiTheme->dumped_images)) {
326 @mkdir("$directory/images");
327 foreach ($WikiTheme->dumped_images as $img_file) {
328 if (($from = $WikiTheme->_findFile($img_file)) and basename($from)) {
329 $target = "$directory/images/".basename($img_file);
330 if (copy($WikiTheme->_path . $from, $target)) {
331 $msg = HTML(HTML::br(), HTML($from), HTML::small(fmt("... copied to %s", $target)));
335 $msg = HTML(HTML::br(), HTML($from), HTML::small(fmt("... not found", $target)));
340 if (is_array($WikiTheme->dumped_css)) {
341 foreach ($WikiTheme->dumped_css as $css_file) {
342 if (($from = $WikiTheme->_findFile(basename($css_file))) and basename($from)) {
343 $target = "$directory/" . basename($css_file);
344 if (copy($WikiTheme->_path . $from, $target)) {
345 $msg = HTML(HTML::br(), HTML($from), HTML::small(fmt("... copied to %s", $target)));
349 $msg = HTML(HTML::br(), HTML($from), HTML::small(fmt("... not found", $target)));
354 $WikiTheme->HTML_DUMP_SUFFIX = '';
355 $WikiTheme->DUMP_MODE = false;
357 $request->setArg('pagename',$thispage); // Template::_basepage fix
358 EndLoadDump($request);
361 /* Known problem: any plugins or other code which echo()s text will
362 * lead to a corrupted html zip file which may produce the following
363 * errors upon unzipping:
365 * warning [wikihtml.zip]: 2401 extra bytes at beginning or within zipfile
366 * file #58: bad zipfile offset (local header sig): 177561
367 * (attempting to re-compensate)
369 * However, the actual wiki page data should be unaffected.
371 function MakeWikiZipHtml (&$request)
373 $zipname = "wikihtml.zip";
374 $zip = new ZipWriter("Created by PhpWiki " . PHPWIKI_VERSION, $zipname);
375 $dbi = $request->getDbh();
376 $pages = $dbi->getAllPages();
379 if (defined('HTML_DUMP_SUFFIX'))
380 $WikiTheme->HTML_DUMP_SUFFIX = HTML_DUMP_SUFFIX;
382 /* ignore fatals in plugins */
383 global $ErrorManager;
384 $ErrorManager->pushErrorHandler(new WikiFunctionCb('_ignore_fatal_plugin_error_handler'));
386 while ($page = $pages->next()) {
387 if (! $request->getArg('start_debug'))
388 @set_time_limit(30); // Reset watchdog.
390 $current = $page->getCurrentRevision();
391 if ($current->getVersion() == 0)
394 $attrib = array('mtime' => $current->get('mtime'),
396 if ($page->get('locked'))
397 $attrib['write_protected'] = 1;
399 $pagename = $page->getName();
400 $request->setArg('pagename',$pagename); // Template::_basepage fix
401 $filename = FilenameForPage($pagename) . $WikiTheme->HTML_DUMP_SUFFIX;
402 $revision = $page->getCurrentRevision();
404 $transformedContent = $revision->getTransformedContent();
406 $template = new Template('browse', $request,
407 array('revision' => $revision,
408 'CONTENT' => $transformedContent));
410 $data = GeneratePageasXML($template, $pagename);
412 $zip->addRegularFile( $filename, $data, $attrib);
414 // FIXME: Deal with images here.
416 $ErrorManager->popErrorHandler();
417 $WikiTheme->$HTML_DUMP_SUFFIX = '';
421 ////////////////////////////////////////////////////////////////
423 // Functions for restoring.
425 ////////////////////////////////////////////////////////////////
427 function SavePage (&$request, $pageinfo, $source, $filename)
429 $pagedata = $pageinfo['pagedata']; // Page level meta-data.
430 $versiondata = $pageinfo['versiondata']; // Revision level meta-data.
432 if (empty($pageinfo['pagename'])) {
433 PrintXML(HTML::dt(HTML::strong(_("Empty pagename!"))));
437 if (empty($versiondata['author_id']))
438 $versiondata['author_id'] = $versiondata['author'];
440 $pagename = $pageinfo['pagename'];
441 $content = $pageinfo['content'];
443 if ($pagename ==_("InterWikiMap"))
444 $content = _tryinsertInterWikiMap($content);
446 $dbi = $request->getDbh();
447 $page = $dbi->getPage($pagename);
449 $current = $page->getCurrentRevision();
450 // Try to merge if updated pgsrc contents are different. This
451 // whole thing is hackish
453 // TODO: try merge unless:
454 // if (current contents = default contents && pgsrc_version >=
455 // pgsrc_version) then just upgrade this pgsrc
456 $needs_merge = false;
460 if ($request->getArg('merge')) {
463 else if ($request->getArg('overwrite')) {
467 if ( (! $current->hasDefaultContents())
468 && ($current->getPackedContent() != $content)
469 && ($merging == true) ) {
470 include_once('lib/editpage.php');
471 $request->setArg('pagename', $pagename);
472 $r = $current->getVersion();
473 $request->setArg('revision', $current->getVersion());
474 $p = new LoadFileConflictPageEditor($request);
475 $p->_content = $content;
476 $p->_currentVersion = $r - 1;
477 $p->editPage($saveFailed = true);
478 return; //early return
481 foreach ($pagedata as $key => $value) {
483 $page->set($key, $value);
489 $mesg->pushContent(' ', fmt("from %s", $source));
492 $current = $page->getCurrentRevision();
493 if ($current->getVersion() == 0) {
494 $mesg->pushContent(' ', _("new page"));
498 if ( (! $current->hasDefaultContents())
499 && ($current->getPackedContent() != $content) ) {
501 $mesg->pushContent(' ',
502 fmt("has edit conflicts - overwriting anyway"));
504 if (substr_count($source, 'pgsrc')) {
505 $versiondata['author'] = _("The PhpWiki programming team");
506 // but leave authorid as userid who loaded the file
510 $mesg->pushContent(' ', fmt("has edit conflicts - skipped"));
511 $needs_merge = true; // hackish
515 else if ($current->getPackedContent() == $content
516 && $current->get('author') == $versiondata['author']) {
517 // The page metadata is already changed, we don't need a new revision.
518 // This was called previously "is identical to current version %d - skipped"
519 // which is wrong, since the pagedata was stored, not skipped.
520 $mesg->pushContent(' ',
521 fmt("content is identical to current version %d - no new revision created",
522 $current->getVersion()));
529 $new = $page->save($content, WIKIDB_FORCE_CREATE, $versiondata);
531 $mesg->pushContent(' ', fmt("- saved to database as version %d",
532 $new->getVersion()));
536 // hackish, $source contains needed path+filename
537 $f = str_replace(sprintf(_("MIME file %s"), ''), '', $f);
538 $f = str_replace(sprintf(_("Serialized file %s"), ''), '', $f);
539 $f = str_replace(sprintf(_("plain file %s"), ''), '', $f);
540 //check if uploaded file? they pass just the content, but the file is gone
543 $meb = Button(array('action' => 'loadfile',
547 _("PhpWikiAdministration"),
549 $owb = Button(array('action' => 'loadfile',
553 _("PhpWikiAdministration"),
555 $mesg->pushContent(' ', $meb, " ", $owb);
557 $mesg->pushContent(HTML::em(_(" Sorry, cannot merge uploaded files.")));
562 PrintXML(HTML::dt(HTML::em(WikiLink($pagename))), $mesg);
564 PrintXML(HTML::dt(WikiLink($pagename)), $mesg);
568 // action=revert (by diff)
569 function RevertPage (&$request)
572 $pagename = $request->getArg('pagename');
573 $version = $request->getArg('version');
575 PrintXML(HTML::dt(fmt("Revert")," ",WikiLink($pagename)),
576 HTML::dd(_("missing required version argument")));
579 $dbi = $request->getDbh();
580 $page = $dbi->getPage($pagename);
581 $current = $page->getCurrentRevision();
582 if ($current->getVersion() == 0) {
583 $mesg->pushContent(' ', _("no page content"));
584 PrintXML(HTML::dt(fmt("Revert")," ",WikiLink($pagename)),
588 if ($current->getVersion() == $version) {
589 $mesg->pushContent(' ', _("same version page"));
592 $rev = $page->getRevision($version);
593 $content = $rev->getPackedContent();
594 $versiondata = $rev->_data;
595 $versiondata['summary'] = sprintf(_("revert to version %d"), $version);
596 $new = $page->save($content, $current->getVersion() + 1, $versiondata);
598 $mesg->pushContent(' ', fmt("- version %d saved to database as version %d",
599 $version, $new->getVersion()));
600 PrintXML(HTML::dt(fmt("Revert")," ",WikiLink($pagename)),
605 function _tryinsertInterWikiMap($content) {
607 if (strpos($content, "<verbatim>")) {
608 //$error_html = " The newly loaded pgsrc already contains a verbatim block.";
611 if (!$goback && !defined('INTERWIKI_MAP_FILE')) {
612 $error_html = sprintf(" "._("%s: not defined"), "INTERWIKI_MAP_FILE");
615 $mapfile = FindFile(INTERWIKI_MAP_FILE,1);
616 if (!$goback && !file_exists($mapfile)) {
617 $error_html = sprintf(" "._("%s: file not found"), INTERWIKI_MAP_FILE);
621 if (!empty($error_html))
622 trigger_error(_("Default InterWiki map file not loaded.")
623 . $error_html, E_USER_NOTICE);
627 // if loading from virgin setup do echo, otherwise trigger_error E_USER_NOTICE
628 echo sprintf(_("Loading InterWikiMap from external file %s."), $mapfile),"<br />";
630 $fd = fopen ($mapfile, "rb");
631 $data = fread ($fd, filesize($mapfile));
633 $content = $content . "\n<verbatim>\n$data</verbatim>\n";
637 function ParseSerializedPage($text, $default_pagename, $user)
639 if (!preg_match('/^a:\d+:{[si]:\d+/', $text))
642 $pagehash = unserialize($text);
644 // Split up pagehash into four parts:
647 // page-level meta-data
648 // revision-level meta-data
650 if (!defined('FLAG_PAGE_LOCKED'))
651 define('FLAG_PAGE_LOCKED', 1);
652 $pageinfo = array('pagedata' => array(),
653 'versiondata' => array());
655 $pagedata = &$pageinfo['pagedata'];
656 $versiondata = &$pageinfo['versiondata'];
659 if (empty($pagehash['pagename']))
660 $pagehash['pagename'] = $default_pagename;
661 if (empty($pagehash['author'])) {
662 $pagehash['author'] = $user->getId();
665 foreach ($pagehash as $key => $value) {
670 $pageinfo[$key] = $value;
673 $pageinfo[$key] = join("\n", $value);
676 if (($value & FLAG_PAGE_LOCKED) != 0)
677 $pagedata['locked'] = 'yes';
681 $pagedata[$key] = $value;
685 $pagedata['perm'] = ParseMimeifiedPerm($value);
688 $versiondata['mtime'] = $value;
693 $versiondata[$key] = $value;
700 function SortByPageVersion ($a, $b) {
701 return $a['version'] - $b['version'];
704 function LoadFile (&$request, $filename, $text = false, $mtime = false)
706 if (!is_string($text)) {
708 $stat = stat($filename);
710 $text = implode("", file($filename));
713 if (! $request->getArg('start_debug'))
714 @set_time_limit(30); // Reset watchdog.
716 // FIXME: basename("filewithnoslashes") seems to return garbage sometimes.
717 $basename = basename("/dummy/" . $filename);
720 $mtime = time(); // Last resort.
722 $default_pagename = rawurldecode($basename);
724 if ( ($parts = ParseMimeifiedPages($text)) ) {
725 usort($parts, 'SortByPageVersion');
726 foreach ($parts as $pageinfo)
727 SavePage($request, $pageinfo, sprintf(_("MIME file %s"),
728 $filename), $basename);
730 else if ( ($pageinfo = ParseSerializedPage($text, $default_pagename,
731 $request->getUser())) ) {
732 SavePage($request, $pageinfo, sprintf(_("Serialized file %s"),
733 $filename), $basename);
736 $user = $request->getUser();
738 // Assume plain text file.
739 $pageinfo = array('pagename' => $default_pagename,
740 'pagedata' => array(),
742 => array('author' => $user->getId()),
743 'content' => preg_replace('/[ \t\r]*\n/', "\n",
746 SavePage($request, $pageinfo, sprintf(_("plain file %s"), $filename),
751 function LoadZip (&$request, $zipfile, $files = false, $exclude = false) {
752 $zip = new ZipReader($zipfile);
753 while (list ($fn, $data, $attrib) = $zip->readFile()) {
754 // FIXME: basename("filewithnoslashes") seems to return
755 // garbage sometimes.
756 $fn = basename("/dummy/" . $fn);
757 if ( ($files && !in_array($fn, $files))
758 || ($exclude && in_array($fn, $exclude)) ) {
759 PrintXML(HTML::dt(WikiLink($fn)),
760 HTML::dd(_("Skipping")));
764 LoadFile($request, $fn, $data, $attrib['mtime']);
768 function LoadDir (&$request, $dirname, $files = false, $exclude = false) {
769 $fileset = new LimitedFileSet($dirname, $files, $exclude);
771 if (!$files and ($skiplist = $fileset->getSkippedFiles())) {
772 PrintXML(HTML::dt(HTML::strong(_("Skipping"))));
774 foreach ($skiplist as $file)
775 $list->pushContent(HTML::li(WikiLink($file)));
776 PrintXML(HTML::dd($list));
779 // Defer HomePage loading until the end. If anything goes wrong
780 // the pages can still be loaded again.
781 $files = $fileset->getFiles();
782 if (in_array(HOME_PAGE, $files)) {
783 $files = array_diff($files, array(HOME_PAGE));
784 $files[] = HOME_PAGE;
786 foreach ($files as $file) {
787 if (substr($file,-1,1) != '~') // refuse to load backup files
788 LoadFile($request, "$dirname/$file");
792 class LimitedFileSet extends FileSet {
793 function LimitedFileSet($dirname, $_include, $exclude) {
794 $this->_includefiles = $_include;
795 $this->_exclude = $exclude;
796 $this->_skiplist = array();
797 parent::FileSet($dirname);
800 function _filenameSelector($fn) {
801 $incl = &$this->_includefiles;
802 $excl = &$this->_exclude;
804 if ( ($incl && !in_array($fn, $incl))
805 || ($excl && in_array($fn, $excl)) ) {
806 $this->_skiplist[] = $fn;
813 function getSkippedFiles () {
814 return $this->_skiplist;
819 function IsZipFile ($filename_or_fd)
821 // See if it looks like zip file
822 if (is_string($filename_or_fd))
824 $fd = fopen($filename_or_fd, "rb");
825 $magic = fread($fd, 4);
830 $fpos = ftell($filename_or_fd);
831 $magic = fread($filename_or_fd, 4);
832 fseek($filename_or_fd, $fpos);
835 return $magic == ZIP_LOCHEAD_MAGIC || $magic == ZIP_CENTHEAD_MAGIC;
839 function LoadAny (&$request, $file_or_dir, $files = false, $exclude = false)
841 // Try urlencoded filename for accented characters.
842 if (!file_exists($file_or_dir)) {
843 // Make sure there are slashes first to avoid confusing phps
844 // with broken dirname or basename functions.
845 // FIXME: windows uses \ and :
846 if (is_integer(strpos($file_or_dir, "/"))) {
847 $file_or_dir = FindFile($file_or_dir);
849 if (!file_exists($file_or_dir))
850 $file_or_dir = dirname($file_or_dir) . "/"
851 . urlencode(basename($file_or_dir));
853 // This is probably just a file.
854 $file_or_dir = urlencode($file_or_dir);
858 $type = filetype($file_or_dir);
859 if ($type == 'link') {
860 // For symbolic links, use stat() to determine
861 // the type of the underlying file.
862 list(,,$mode) = stat($file_or_dir);
863 $type = ($mode >> 12) & 017;
866 elseif ($type == 004)
871 $request->finish(fmt("Unable to load: %s", $file_or_dir));
873 else if ($type == 'dir') {
874 LoadDir($request, $file_or_dir, $files, $exclude);
876 else if ($type != 'file' && !preg_match('/^(http|ftp):/', $file_or_dir))
878 $request->finish(fmt("Bad file type: %s", $type));
880 else if (IsZipFile($file_or_dir)) {
881 LoadZip($request, $file_or_dir, $files, $exclude);
883 else /* if (!$files || in_array(basename($file_or_dir), $files)) */
885 LoadFile($request, $file_or_dir);
889 function LoadFileOrDir (&$request)
891 $source = $request->getArg('source');
892 $finder = new FileFinder;
893 $source = $finder->slashifyPath($source);
894 $page = rawurldecode(basename($source));
895 StartLoadDump($request, fmt("Loading '%s'",
896 HTML(dirname($source),
897 dirname($source) ? "/" : "",
898 WikiLink($page,'auto'))));
900 LoadAny($request, $source);
902 EndLoadDump($request);
905 function SetupWiki (&$request)
907 global $GenericPages, $LANG;
910 //FIXME: This is a hack (err, "interim solution")
911 // This is a bogo-bogo-login: Login without
912 // saving login information in session state.
913 // This avoids logging in the unsuspecting
914 // visitor as "The PhpWiki programming team".
916 // This really needs to be cleaned up...
917 // (I'm working on it.)
918 $real_user = $request->_user;
920 $request->_user = new _BogoUser(_("The PhpWiki programming team"));
923 $request->_user = new WikiUser($request, _("The PhpWiki programming team"),
926 StartLoadDump($request, _("Loading up virgin wiki"));
929 $pgsrc = FindLocalizedFile(WIKI_PGSRC);
930 $default_pgsrc = FindFile(DEFAULT_WIKI_PGSRC);
932 $request->setArg('overwrite',true);
933 if ($default_pgsrc != $pgsrc) {
934 LoadAny($request, $default_pgsrc, $GenericPages);
936 $request->setArg('overwrite',false);
937 LoadAny($request, $pgsrc);
939 // Ensure that all mandatory pages are loaded
940 $finder = new FileFinder;
941 foreach (array_merge(explode(':','OldTextFormattingRules:TextFormattingRules:PhpWikiAdministration'),
942 $GLOBALS['AllActionPages'],
943 array(constant('HOME_PAGE'))) as $f) {
945 if (isSubPage($page))
946 $page = urlencode($page);
947 if (! $request->_dbi->isWikiPage(urldecode($page)) ) {
948 // translated version provided?
949 if ($lf = FindLocalizedFile($pgsrc . $finder->_pathsep . $page, 1))
950 LoadAny($request, $lf);
951 else { // load english version of required action page
952 LoadAny($request, FindFile(DEFAULT_WIKI_PGSRC . $finder->_pathsep . urlencode($f)));
956 if (!$request->_dbi->isWikiPage(urldecode($page))) {
957 trigger_error(sprintf("Mandatory file %s couldn't be loaded!", $page),
963 EndLoadDump($request);
966 function LoadPostFile (&$request)
968 $upload = $request->getUploadedFile('file');
971 $request->finish(_("No uploaded file to upload?")); // FIXME: more concise message
974 // Dump http headers.
975 StartLoadDump($request, sprintf(_("Uploading %s"), $upload->getName()));
978 $fd = $upload->open();
980 LoadZip($request, $fd, false, array(_("RecentChanges")));
982 LoadFile($request, $upload->getName(), $upload->getContents());
985 EndLoadDump($request);
989 $Log: not supported by cvs2svn $
990 Revision 1.106 2004/06/13 13:54:25 rurban
991 Catch fatals on the four dump calls (as file and zip, as html and mimified)
992 FoafViewer: Check against external requirements, instead of fatal.
993 Change output for xhtmldumps: using file:// urls to the local fs.
994 Catch SOAP fatal by checking for GOOGLE_LICENSE_KEY
995 Import GOOGLE_LICENSE_KEY and FORTUNE_DIR from config.ini.
997 Revision 1.105 2004/06/08 19:48:16 rurban
998 fixed foreign setup: no ugly skipped msg for the GenericPages, load english actionpages if translated not found
1000 Revision 1.104 2004/06/08 13:51:57 rurban
1003 Revision 1.103 2004/06/08 10:54:46 rurban
1004 better acl dump representation, read back acl and owner
1006 Revision 1.102 2004/06/06 16:58:51 rurban
1007 added more required ActionPages for foreign languages
1008 install now english ActionPages if no localized are found. (again)
1009 fixed default anon user level to be 0, instead of -1
1010 (wrong "required administrator to view this page"...)
1012 Revision 1.101 2004/06/04 20:32:53 rurban
1013 Several locale related improvements suggested by Pierrick Meignen
1014 LDAP fix by John Cole
1015 reanable admin check without ENABLE_PAGEPERM in the admin plugins
1017 Revision 1.100 2004/05/02 21:26:38 rurban
1018 limit user session data (HomePageHandle and auth_dbi have to invalidated anyway)
1019 because they will not survive db sessions, if too large.
1020 extended action=upgrade
1021 some WikiTranslation button work
1022 revert WIKIAUTH_UNOBTAINABLE (need it for main.php)
1023 some temp. session debug statements
1025 Revision 1.99 2004/05/02 15:10:07 rurban
1026 new finally reliable way to detect if /index.php is called directly
1027 and if to include lib/main.php
1028 new global AllActionPages
1029 SetupWiki now loads all mandatory pages: HOME_PAGE, action pages, and warns if not.
1030 WikiTranslation what=buttons for Carsten to create the missing MacOSX buttons
1031 PageGroupTestOne => subpages
1032 renamed PhpWikiRss to PhpWikiRecentChanges
1033 more docs, default configs, ...
1035 Revision 1.98 2004/04/29 23:25:12 rurban
1036 re-ordered locale init (as in 1.3.9)
1037 fixed loadfile with subpages, and merge/restore anyway
1038 (sf.net bug #844188)
1040 Revision 1.96 2004/04/19 23:13:03 zorloc
1041 Connect the rest of PhpWiki to the IniConfig system. Also the keyword regular expression is not a config setting
1043 Revision 1.95 2004/04/18 01:11:52 rurban
1044 more numeric pagename fixes.
1045 fixed action=upload with merge conflict warnings.
1046 charset changed from constant to global (dynamic utf-8 switching)
1048 Revision 1.94 2004/03/14 16:36:37 rurban
1049 dont load backup files
1051 Revision 1.93 2004/02/26 03:22:05 rurban
1052 also copy css and images with XHTML Dump
1054 Revision 1.92 2004/02/26 02:25:54 rurban
1055 fix empty and #-anchored links in XHTML Dumps
1057 Revision 1.91 2004/02/24 17:19:37 rurban
1058 debugging helpers only
1060 Revision 1.90 2004/02/24 17:09:24 rurban
1061 fixed \r\r\n with dumping on windows
1063 Revision 1.88 2004/02/22 23:20:31 rurban
1064 fixed DumpHtmlToDir,
1065 enhanced sortby handling in PageList
1066 new button_heading th style (enabled),
1067 added sortby and limit support to the db backends and plugins
1068 for paging support (<<prev, next>> links on long lists)
1070 Revision 1.87 2004/01/26 09:17:49 rurban
1071 * changed stored pref representation as before.
1072 the array of objects is 1) bigger and 2)
1073 less portable. If we would import packed pref
1074 objects and the object definition was changed, PHP would fail.
1075 This doesn't happen with an simple array of non-default values.
1076 * use $prefs->retrieve and $prefs->store methods, where retrieve
1077 understands the interim format of array of objects also.
1078 * simplified $prefs->get() and fixed $prefs->set()
1079 * added $user->_userid and class '_WikiUser' portability functions
1080 * fixed $user object ->_level upgrading, mostly using sessions.
1081 this fixes yesterdays problems with loosing authorization level.
1082 * fixed WikiUserNew::checkPass to return the _level
1083 * fixed WikiUserNew::isSignedIn
1084 * added explodePageList to class PageList, support sortby arg
1085 * fixed UserPreferences for WikiUserNew
1086 * fixed WikiPlugin for empty defaults array
1087 * UnfoldSubpages: added pagename arg, renamed pages arg,
1088 removed sort arg, support sortby arg
1090 Revision 1.86 2003/12/02 16:18:26 carstenklapp
1091 Minor enhancement: Provide more meaningful filenames for WikiDB zip
1094 Revision 1.85 2003/11/30 18:18:13 carstenklapp
1095 Minor code optimization: use include_once instead of require_once
1096 inside functions that might not always called.
1098 Revision 1.84 2003/11/26 20:47:47 carstenklapp
1099 Redo bugfix: My last refactoring broke merge-edit & overwrite
1100 functionality again, should be fixed now. Sorry.
1102 Revision 1.83 2003/11/20 22:18:54 carstenklapp
1103 New feature: h1 during merge-edit displays WikiLink to original page.
1104 Internal changes: Replaced some hackish url-generation code in
1105 function SavePage (for pgsrc merge-edit) with appropriate Button()
1108 Revision 1.82 2003/11/18 19:48:01 carstenklapp
1109 Fixed missing gettext _() for button name.
1111 Revision 1.81 2003/11/18 18:28:35 carstenklapp
1112 Bugfix: In the Load File function of PhpWikiAdministration: When doing
1113 a "Merge Edit" or "Restore Anyway", page names containing accented
1114 letters (such as locale/de/pgsrc/G%E4steBuch) would produce a file not
1115 found error (Use FilenameForPage funtion to urlencode page names).
1117 Revision 1.80 2003/03/07 02:46:57 dairiki
1118 Omit checks for safe_mode before set_time_limit(). Just prefix the
1119 set_time_limit() calls with @ so that they fail silently if not
1122 Revision 1.79 2003/02/26 01:56:05 dairiki
1123 Only zip pages with legal pagenames.
1125 Revision 1.78 2003/02/24 02:05:43 dairiki
1126 Fix "n bytes written" message when dumping HTML.
1128 Revision 1.77 2003/02/21 04:12:05 dairiki
1129 Minor fixes for new cached markup.
1131 Revision 1.76 2003/02/16 19:47:17 dairiki
1132 Update WikiDB timestamp when editing or deleting pages.
1134 Revision 1.75 2003/02/15 03:04:30 dairiki
1135 Fix for WikiUser constructor API change.
1137 Revision 1.74 2003/02/15 02:18:04 dairiki
1138 When default language was English (at least), pgsrc was being
1141 LimitedFileSet: Fix typo/bug. ($include was being ignored.)
1143 SetupWiki(): Fix bugs in loading of $GenericPages.
1145 Revision 1.73 2003/01/28 21:09:17 zorloc
1146 The get_cfg_var() function should only be used when one is
1147 interested in the value from php.ini or similar. Use ini_get()
1148 instead to get the effective value of a configuration variable.
1151 Revision 1.72 2003/01/03 22:25:53 carstenklapp
1152 Cosmetic fix to "Merge Edit" & "Overwrite" buttons. Added "The PhpWiki
1153 programming team" as author when loading from pgsrc. Source
1156 Revision 1.71 2003/01/03 02:48:05 carstenklapp
1157 function SavePage: Added loadfile options for overwriting or merge &
1158 compare a loaded pgsrc file with an existing page.
1160 function LoadAny: Added a general error message when unable to load a
1161 file instead of defaulting to "Bad file type".
1169 // c-basic-offset: 4
1170 // c-hanging-comment-ender-p: nil
1171 // indent-tabs-mode: nil