5 Copyright 1999,2000,2001,2002,2004,2005,2006,2007 $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
24 require_once("lib/ziplib.php");
25 require_once("lib/Template.php");
28 * ignore fatal errors during dump
30 function _dump_error_handler(&$error) {
31 if ($error->isFatal()) {
32 $error->errno = E_USER_WARNING;
35 return true; // Ignore error
37 if (preg_match('/Plugin/', $error->errstr))
40 // let the message come through: call the remaining handlers:
44 function StartLoadDump(&$request, $title, $html = '')
46 // MockRequest is from the unit testsuite, a faked request. (may be cmd-line)
47 // We are silent on unittests.
48 if (isa($request,'MockRequest'))
50 // FIXME: This is a hack. This really is the worst overall hack in phpwiki.
52 $html->pushContent('%BODY%');
53 $tmpl = Template('html', array('TITLE' => $title,
55 'CONTENT' => $html ? $html : '%BODY%'));
56 echo ereg_replace('%BODY%.*', '', $tmpl->getExpansion($html));
57 $request->chunkOutput();
59 // set marker for sendPageChangeNotification()
60 $request->_deferredPageChangeNotification = array();
63 function EndLoadDump(&$request)
67 if (isa($request,'MockRequest'))
69 $action = $request->getArg('action');
72 case 'zip': $label = _("ZIP files of database"); break;
73 case 'dumpserial': $label = _("Dump to directory"); break;
74 case 'upload': $label = _("Upload File"); break;
75 case 'loadfile': $label = _("Load File"); break;
76 case 'upgrade': $label = _("Upgrade"); break;
78 case 'ziphtml': $label = _("Dump pages as XHTML"); break;
80 if ($label) $label = str_replace(" ","_",$label);
81 if ($action == 'browse') // loading virgin
82 $pagelink = WikiLink(HOME_PAGE);
84 $pagelink = WikiLink(new WikiPageName(_("PhpWikiAdministration"),false,$label));
86 // do deferred sendPageChangeNotification()
87 if (!empty($request->_deferredPageChangeNotification)) {
88 $pages = $all_emails = $all_users = array();
89 foreach ($request->_deferredPageChangeNotification as $p) {
90 list($pagename, $emails, $userids) = $p;
92 $all_emails = array_unique(array_merge($all_emails, $emails));
93 $all_users = array_unique(array_merge($all_users, $userids));
95 $editedby = sprintf(_("Edited by: %s"), $request->_user->getId());
96 $content = "Loaded the following pages:\n" . join("\n", $pages);
97 if (mail(join(',',$all_emails),"[".WIKI_NAME."] "._("LoadDump"),
101 trigger_error(sprintf(_("PageChange Notification of %s sent to %s"),
102 join("\n",$pages), join(',',$all_users)), E_USER_NOTICE);
104 trigger_error(sprintf(_("PageChange Notification Error: Couldn't send %s to %s"),
105 join("\n",$pages), join(',',$all_users)), E_USER_WARNING);
110 unset($request->_deferredPageChangeNotification);
112 PrintXML(HTML::p(HTML::strong(_("Complete."))),
113 HTML::p(fmt("Return to %s", $pagelink)));
114 // Ugly hack to get valid XHTML code
115 if (isa($WikiTheme, 'Theme_gforge')) {
122 echo "</body></html>\n";
126 ////////////////////////////////////////////////////////////////
128 // Functions for dumping.
130 ////////////////////////////////////////////////////////////////
134 * http://www.nacs.uci.edu/indiv/ehood/MIME/2045/rfc2045.html
135 * http://www.faqs.org/rfcs/rfc2045.html
136 * (RFC 1521 has been superceeded by RFC 2045 & others).
138 * Also see http://www.faqs.org/rfcs/rfc2822.html
140 function MailifyPage ($page, $nversions = 1)
142 $current = $page->getCurrentRevision(false);
145 if (STRICT_MAILABLE_PAGEDUMPS) {
146 $from = defined('SERVER_ADMIN') ? SERVER_ADMIN : 'foo@bar';
147 //This is for unix mailbox format: (not RFC (2)822)
148 // $head .= "From $from " . CTime(time()) . "\r\n";
149 $head .= "Subject: " . rawurlencode($page->getName()) . "\r\n";
150 $head .= "From: $from (PhpWiki)\r\n";
151 // RFC 2822 requires only a Date: and originator (From:)
152 // field, however the obsolete standard RFC 822 also
153 // requires a destination field.
154 $head .= "To: $from (PhpWiki)\r\n";
156 $head .= "Date: " . Rfc2822DateTime($current->get('mtime')) . "\r\n";
157 $head .= sprintf("Mime-Version: 1.0 (Produced by PhpWiki %s)\r\n",
160 // This should just be entered by hand (or by script?)
161 // in the actual pgsrc files, since only they should have
163 //$head .= "X-Rcs-Id: \$Id\$\r\n";
165 $iter = $page->getAllRevisions();
167 while ($revision = $iter->next()) {
168 $parts[] = MimeifyPageRevision($page, $revision);
169 if ($nversions > 0 && count($parts) >= $nversions)
172 if (count($parts) > 1)
173 return $head . MimeMultipart($parts);
175 return $head . $parts[0];
179 * Compute filename to used for storing contents of a wiki page.
181 * Basically we do a rawurlencode() which encodes everything except
182 * ASCII alphanumerics and '.', '-', and '_'.
184 * But we also want to encode leading dots to avoid filenames like
185 * '.', and '..'. (Also, there's no point in generating "hidden" file
186 * names, like '.foo'.)
188 * We have to apply a different "/" logic for dumpserial, htmldump and zipdump.
189 * dirs are allowed for zipdump and htmldump, not for dumpserial
192 * @param $pagename string Pagename.
193 * @return string Filename for page.
195 function FilenameForPage ($pagename, $action = false)
197 $enc = rawurlencode($pagename);
200 $action = $request->getArg('action');
202 if ($action != 'dumpserial') { // zip, ziphtml, dumphtml
203 // For every %2F we will need to mkdir -p dirname($pagename)
204 $enc = preg_replace('/%2F/', '/', $enc);
206 $enc = preg_replace('/^\./', '%2E', $enc);
207 $enc = preg_replace('/%20/', ' ', $enc);
212 * The main() function which generates a zip archive of a PhpWiki.
214 * If $include_archive is false, only the current version of each page
215 * is included in the zip file; otherwise all archived versions are
218 function MakeWikiZip (&$request)
220 if ($request->getArg('include') == 'all') {
221 $zipname = WIKI_NAME . _("FullDump") . date('Ymd-Hi') . '.zip';
222 $include_archive = true;
225 $zipname = WIKI_NAME . _("LatestSnapshot") . date('Ymd-Hi') . '.zip';
226 $include_archive = false;
230 $zip = new ZipWriter("Created by PhpWiki " . PHPWIKI_VERSION, $zipname);
232 /* ignore fatals in plugins */
233 if (check_php_version(4,1)) {
234 global $ErrorManager;
235 $ErrorManager->pushErrorHandler(new WikiFunctionCb('_dump_error_handler'));
238 $dbi =& $request->_dbi;
239 $thispage = $request->getArg('pagename'); // for "Return to ..."
240 if ($exclude = $request->getArg('exclude')) { // exclude which pagenames
241 $excludeList = explodePageList($exclude);
243 $excludeList = array();
245 if ($pages = $request->getArg('pages')) { // which pagenames
246 if ($pages == '[]') // current page
248 $page_iter = new WikiDB_Array_PageIterator(explodePageList($pages));
250 $page_iter = $dbi->getAllPages(false,false,false,$excludeList);
252 $request_args = $request->args;
253 $timeout = (! $request->getArg('start_debug')) ? 30 : 240;
255 while ($page = $page_iter->next()) {
256 $request->args = $request_args; // some plugins might change them (esp. on POST)
257 longer_timeout($timeout); // Reset watchdog
259 $current = $page->getCurrentRevision();
260 if ($current->getVersion() == 0)
263 $pagename = $page->getName();
264 $wpn = new WikiPageName($pagename);
265 if (!$wpn->isValid())
267 if (in_array($page->getName(), $excludeList)) {
271 $attrib = array('mtime' => $current->get('mtime'),
273 if ($page->get('locked'))
274 $attrib['write_protected'] = 1;
276 if ($include_archive)
277 $content = MailifyPage($page, 0);
279 $content = MailifyPage($page);
281 $zip->addRegularFile( FilenameForPage($pagename),
285 if (check_php_version(4,1)) {
286 global $ErrorManager;
287 $ErrorManager->popErrorHandler();
291 function DumpToDir (&$request)
293 $directory = $request->getArg('directory');
294 if (empty($directory))
295 $directory = DEFAULT_DUMP_DIR; // See lib/plugin/WikiForm.php:87
296 if (empty($directory))
297 $request->finish(_("You must specify a directory to dump to"));
299 // see if we can access the directory the user wants us to use
300 if (! file_exists($directory)) {
301 if (! mkdir($directory, 0755))
302 $request->finish(fmt("Cannot create directory '%s'", $directory));
304 $html = HTML::p(fmt("Created directory '%s' for the page dump...",
307 $html = HTML::p(fmt("Using directory '%s'", $directory));
310 StartLoadDump($request, _("Dumping Pages"), $html);
312 $dbi =& $request->_dbi;
313 $thispage = $request->getArg('pagename'); // for "Return to ..."
314 if ($exclude = $request->getArg('exclude')) { // exclude which pagenames
315 $excludeList = explodePageList($exclude);
317 $excludeList = array();
319 if ($pages = $request->getArg('pages')) { // which pagenames
320 if ($pages == '[]') // current page
322 $page_iter = new WikiDB_Array_PageIterator(explodePageList($pages));
324 $page_iter = $dbi->getAllPages(false,false,false,$excludeList);
327 $request_args = $request->args;
328 $timeout = (! $request->getArg('start_debug')) ? 30 : 240;
330 while ($page = $page_iter->next()) {
331 $request->args = $request_args; // some plugins might change them (esp. on POST)
332 longer_timeout($timeout); // Reset watchdog
334 $pagename = $page->getName();
335 if (!isa($request,'MockRequest')) {
336 PrintXML(HTML::br(), $pagename, ' ... ');
340 if (in_array($pagename, $excludeList)) {
341 if (!isa($request, 'MockRequest')) {
342 PrintXML(_("Skipped."));
347 $filename = FilenameForPage($pagename);
349 if($page->getName() != $filename) {
350 $msg->pushContent(HTML::small(fmt("saved as %s", $filename)),
354 if ($request->getArg('include') == 'all')
355 $data = MailifyPage($page, 0);
357 $data = MailifyPage($page);
359 if ( !($fd = fopen($directory."/".$filename, "wb")) ) {
360 $msg->pushContent(HTML::strong(fmt("couldn't open file '%s' for writing",
361 "$directory/$filename")));
362 $request->finish($msg);
365 $num = fwrite($fd, $data, strlen($data));
366 $msg->pushContent(HTML::small(fmt("%s bytes written", $num)));
367 if (!isa($request, 'MockRequest')) {
371 assert($num == strlen($data));
375 EndLoadDump($request);
378 function _copyMsg($page, $smallmsg) {
379 if (!isa($GLOBALS['request'], 'MockRequest')) {
380 if ($page) $msg = HTML(HTML::br(), HTML($page), HTML::small($smallmsg));
381 else $msg = HTML::small($smallmsg);
387 function mkdir_p($pathname, $permission = 0777) {
388 $arr = explode("/", $pathname);
390 return mkdir($pathname, $permission);
392 $s = array_shift($arr);
394 foreach ($arr as $p) {
397 $ok = mkdir($curr, $permission);
399 if (!$ok) return FALSE;
405 * Dump all pages as XHTML to a directory, as pagename.html.
406 * Copies all used css files to the directory, all used images to a
407 * "images" subdirectory, and all used buttons to a "images/buttons" subdirectory.
408 * The webserver must have write permissions to these directories.
409 * chown httpd HTML_DUMP_DIR; chmod u+rwx HTML_DUMP_DIR
412 * @param string directory (optional) path to dump to. Default: HTML_DUMP_DIR
413 * @param string pages (optional) Comma-seperated of glob-style pagenames to dump.
414 * Also array of pagenames allowed.
415 * @param string exclude (optional) Comma-seperated of glob-style pagenames to exclude
417 function DumpHtmlToDir (&$request)
420 $directory = $request->getArg('directory');
421 if (empty($directory))
422 $directory = HTML_DUMP_DIR; // See lib/plugin/WikiForm.php:87
423 if (empty($directory))
424 $request->finish(_("You must specify a directory to dump to"));
426 // See if we can access the directory the user wants us to use
427 if (! file_exists($directory)) {
428 if (! mkdir($directory, 0755))
429 $request->finish(fmt("Cannot create directory '%s'", $directory));
431 $html = HTML::p(fmt("Created directory '%s' for the page dump...",
434 $html = HTML::p(fmt("Using directory '%s'", $directory));
436 StartLoadDump($request, _("Dumping Pages"), $html);
437 $thispage = $request->getArg('pagename'); // for "Return to ..."
439 $dbi =& $request->_dbi;
440 if ($exclude = $request->getArg('exclude')) { // exclude which pagenames
441 $excludeList = explodePageList($exclude);
443 $excludeList = array('DebugAuthInfo', 'DebugGroupInfo', 'AuthInfo');
445 if ($pages = $request->getArg('pages')) { // which pagenames
446 if ($pages == '[]') // current page
448 $page_iter = new WikiDB_Array_generic_iter(explodePageList($pages));
449 // not at admin page: dump only the current page
450 } elseif ($thispage != _("PhpWikiAdministration")) {
451 $page_iter = new WikiDB_Array_generic_iter(array($thispage));
453 $page_iter = $dbi->getAllPages(false,false,false,$excludeList);
456 $WikiTheme->DUMP_MODE = 'HTML';
457 _DumpHtmlToDir($directory, $page_iter, $request->getArg('exclude'));
458 $WikiTheme->DUMP_MODE = false;
460 $request->setArg('pagename',$thispage); // Template::_basepage fix
461 EndLoadDump($request);
464 /* Known problem: any plugins or other code which echo()s text will
465 * lead to a corrupted html zip file which may produce the following
466 * errors upon unzipping:
468 * warning [wikihtml.zip]: 2401 extra bytes at beginning or within zipfile
469 * file #58: bad zipfile offset (local header sig): 177561
470 * (attempting to re-compensate)
472 * However, the actual wiki page data should be unaffected.
474 function MakeWikiZipHtml (&$request)
477 if ($request->getArg('zipname')) {
478 $zipname = basename($request->getArg('zipname'));
479 if (!preg_match("/\.zip$/i", $zipname))
481 $request->setArg('zipname', false);
483 $zipname = "wikihtml.zip";
485 $zip = new ZipWriter("Created by PhpWiki " . PHPWIKI_VERSION, $zipname);
486 $dbi =& $request->_dbi;
487 $thispage = $request->getArg('pagename'); // for "Return to ..."
488 if ($pages = $request->getArg('pages')) { // which pagenames
489 if ($pages == '[]') // current page
491 $page_iter = new WikiDB_Array_generic_iter(explodePageList($pages));
493 $page_iter = $dbi->getAllPages(false,false,false,$request->getArg('exclude'));
496 $WikiTheme->DUMP_MODE = 'ZIPHTML';
497 _DumpHtmlToDir($zip, $page_iter, $request->getArg('exclude'));
498 $WikiTheme->DUMP_MODE = false;
502 * Internal html dumper. Used for dumphtml, ziphtml and pdf
504 function _DumpHtmlToDir ($target, $page_iter, $exclude = false)
506 global $WikiTheme, $request;
507 $silent = true; $zip = false; $directory = false;
508 if ($WikiTheme->DUMP_MODE == 'HTML') {
509 $directory = $target;
511 } elseif ($WikiTheme->DUMP_MODE == 'PDFHTML') {
512 $directory = $target;
513 } elseif (is_object($target)) { // $WikiTheme->DUMP_MODE == 'ZIPHTML'
517 $request->_TemplatesProcessed = array();
518 if ($exclude) { // exclude which pagenames
519 $excludeList = explodePageList($exclude);
521 $excludeList = array('DebugAuthInfo', 'DebugGroupInfo', 'AuthInfo');
523 $WikiTheme->VALID_LINKS = array();
524 if ($request->getArg('format')) { // pagelist
525 $page_iter_sav = $page_iter;
526 foreach ($page_iter_sav->asArray() as $handle) {
527 $WikiTheme->VALID_LINKS[] = is_string($handle) ? $handle : $handle->getName();
529 $page_iter_sav->reset();
532 if (defined('HTML_DUMP_SUFFIX'))
533 $WikiTheme->HTML_DUMP_SUFFIX = HTML_DUMP_SUFFIX;
534 $_bodyAttr = @$WikiTheme->_MoreAttr['body'];
535 unset($WikiTheme->_MoreAttr['body']);
537 if (check_php_version(4,1)) {
538 global $ErrorManager;
539 $ErrorManager->pushErrorHandler(new WikiFunctionCb('_dump_error_handler'));
542 // check if the dumped file will be accessible from outside
543 $doc_root = $request->get("DOCUMENT_ROOT");
544 if ($WikiTheme->DUMP_MODE == 'HTML') {
545 $ldir = NormalizeLocalFileName($directory);
546 $wikiroot = NormalizeLocalFileName('');
547 if (string_starts_with($ldir, $doc_root)) {
548 $link_prefix = substr($directory, strlen($doc_root))."/";
549 } elseif (string_starts_with($ldir, $wikiroot)) {
550 $link_prefix = NormalizeWebFileName(substr($directory, strlen($wikiroot)))."/";
554 $prefix = '/'; // . substr($doc_root,0,2); // add drive where apache is installed
556 $link_prefix = "file://".$prefix.$directory."/";
562 $request_args = $request->args;
563 $timeout = (! $request->getArg('start_debug')) ? 60 : 240;
564 $SAVE_RCS_IDS = $GLOBALS['RCS_IDS'];
567 $directory = str_replace("\\", "/", $directory); // no Win95 support.
568 @mkdir("$directory/images");
572 $already_images = array();
574 while ($page = $page_iter->next()) {
575 if (is_string($page)) {
577 $page = $request->_dbi->getPage($pagename);
579 $pagename = $page->getName();
581 if (empty($firstpage)) $firstpage = $pagename;
582 if (array_key_exists($pagename, $already))
584 $already[$pagename] = 1;
585 $current = $page->getCurrentRevision();
586 //if ($current->getVersion() == 0)
589 $request->args = $request_args; // some plugins might change them (esp. on POST)
590 longer_timeout($timeout); // Reset watchdog
593 $attrib = array('mtime' => $current->get('mtime'),
595 if ($page->get('locked'))
596 $attrib['write_protected'] = 1;
597 } elseif (!$silent) {
598 if (!isa($request,'MockRequest')) {
599 PrintXML(HTML::br(), $pagename, ' ... ');
603 if (in_array($pagename, $excludeList)) {
604 if (!$silent and !isa($request,'MockRequest')) {
605 PrintXML(_("Skipped."));
611 if ($WikiTheme->DUMP_MODE == 'PDFHTML')
612 $request->setArg('action', 'pdf'); // to omit cache headers
613 $request->setArg('pagename', $pagename); // Template::_basepage fix
614 $filename = FilenameForPage($pagename) . $WikiTheme->HTML_DUMP_SUFFIX;
615 $args = array('revision' => $current,
616 'CONTENT' => $current->getTransformedContent(),
617 'relative_base' => $relative_base);
618 // For every %2F will need to mkdir -p dirname($pagename)
619 if (preg_match("/(%2F|\/)/", $filename)) {
620 // mkdir -p and set relative base for subdir pages
621 $filename = preg_replace("/%2F/", "/", $filename);
622 $count = substr_count($filename, "/");
623 $dirname = dirname($filename);
625 mkdir_p($directory."/".$dirname);
626 // Fails with "XX / YY", "XX" is created, "XX / YY" cannot be written
627 // if (isWindows()) // interesting Windows bug: cannot mkdir "bla "
628 // Since dumps needs to be copied, we have to disallow this for all platforms.
629 $filename = preg_replace("/ \//", "/", $filename);
630 $relative_base = "../";
632 $relative_base .= "../";
635 $args['relative_base'] = $relative_base;
639 $DUMP_MODE = $WikiTheme->DUMP_MODE;
640 $data = GeneratePageasXML(new Template('browse', $request, $args),
641 $pagename, $current, $args);
642 $WikiTheme->DUMP_MODE = $DUMP_MODE;
644 if (preg_match_all("/<img .*?src=\"(\/.+?)\"/", $data, $m)) {
645 // fix to local relative path for uploaded images, so that pdf will work
646 foreach ($m[1] as $img_file) {
647 $base = basename($img_file);
648 $data = str_replace('src="'.$img_file.'"','src="images/'.$base.'"', $data);
649 if (array_key_exists($img_file, $already_images))
651 $already_images[$img_file] = 1;
652 // resolve src from webdata to file
653 $src = $doc_root . $img_file;
654 if (file_exists($src) and $base) {
656 $target = "$directory/images/$base";
657 if (copy($src, $target)) {
659 _copyMsg($img_file, fmt("... copied to %s", $target));
662 _copyMsg($img_file, fmt("... not copied to %s", $target));
665 $target = "images/$base";
666 $zip->addSrcFile($target, $src);
673 $outfile = $directory."/".$filename;
674 if ( !($fd = fopen($outfile, "wb")) ) {
675 $msg->pushContent(HTML::strong(fmt("couldn't open file '%s' for writing",
677 $request->finish($msg);
679 $len = strlen($data);
680 $num = fwrite($fd, $data, $len);
681 if ($pagename != $filename) {
682 $link = LinkURL($link_prefix.$filename, $filename);
683 $msg->pushContent(HTML::small(_("saved as "), $link, " ... "));
685 $msg->pushContent(HTML::small(fmt("%s bytes written", $num), "\n"));
687 if (!isa($request, 'MockRequest')) {
691 $request->chunkOutput();
693 assert($num == $len);
695 $outfiles[] = $outfile;
697 $zip->addRegularFile($filename, $data, $attrib);
701 $request->_dbi->_cache->invalidate_cache($pagename);
702 unset ($request->_dbi->_cache->_pagedata_cache);
703 unset ($request->_dbi->_cache->_versiondata_cache);
704 unset ($request->_dbi->_cache->_glv_cache);
706 unset ($request->_dbi->_cache->_backend->_page_data);
709 unset($current->_transformedContent);
711 if (!empty($template)) {
712 unset($template->_request);
717 $GLOBALS['RCS_IDS'] = $SAVE_RCS_IDS;
721 $attrib = false; //array('is_ascii' => 0);
722 if (!empty($WikiTheme->dumped_images) and is_array($WikiTheme->dumped_images)) {
723 // @mkdir("$directory/images");
724 foreach ($WikiTheme->dumped_images as $img_file) {
725 if (array_key_exists($img_file, $already_images))
727 $already_images[$img_file] = 1;
729 and ($from = $WikiTheme->_findFile($img_file, true))
733 $target = "$directory/images/".basename($from);
735 copy($WikiTheme->_path . $from, $target);
737 if (copy($WikiTheme->_path . $from, $target)) {
738 _copyMsg($from, fmt("... copied to %s", $target));
740 _copyMsg($from, fmt("... not copied to %s", $target));
744 $target = "images/".basename($from);
745 $zip->addSrcFile($target, $WikiTheme->_path . $from);
747 } elseif (!$silent) {
748 _copyMsg($from, _("... not found"));
753 if (!empty($WikiTheme->dumped_buttons)
754 and is_array($WikiTheme->dumped_buttons))
758 @mkdir("$directory/images/buttons");
759 foreach ($WikiTheme->dumped_buttons as $text => $img_file) {
760 if (array_key_exists($img_file, $already_images))
762 $already_images[$img_file] = 1;
764 and ($from = $WikiTheme->_findFile($img_file, true))
768 $target = "$directory/images/buttons/".basename($from);
770 copy($WikiTheme->_path . $from, $target);
772 if (copy($WikiTheme->_path . $from, $target)) {
773 _copyMsg($from, fmt("... copied to %s", $target));
775 _copyMsg($from, fmt("... not copied to %s", $target));
779 $target = "images/buttons/".basename($from);
780 $zip->addSrcFile($target, $WikiTheme->_path . $from);
782 } elseif (!$silent) {
783 _copyMsg($from, _("... not found"));
787 if (!empty($WikiTheme->dumped_css) and is_array($WikiTheme->dumped_css)) {
788 foreach ($WikiTheme->dumped_css as $css_file) {
789 if (array_key_exists($css_file, $already_images))
791 $already_images[$css_file] = 1;
793 and ($from = $WikiTheme->_findFile(basename($css_file), true))
796 // TODO: fix @import url(main.css);
798 $target = "$directory/" . basename($css_file);
800 copy($WikiTheme->_path . $from, $target);
802 if (copy($WikiTheme->_path . $from, $target)) {
803 _copyMsg($from, fmt("... copied to %s", $target));
805 _copyMsg($from, fmt("... not copied to %s", $target));
809 //$attrib = array('is_ascii' => 0);
810 $target = basename($css_file);
811 $zip->addSrcFile($target, $WikiTheme->_path . $from);
813 } elseif (!$silent) {
814 _copyMsg($from, _("... not found"));
822 if ($WikiTheme->DUMP_MODE == 'PDFHTML') {
823 if (USE_EXTERNAL_HTML2PDF and $outfiles) {
824 $cmd = EXTERNAL_HTML2PDF_PAGELIST.' "'.join('" "', $outfiles).'"';
825 $filename = FilenameForPage($firstpage);
827 $tmpfile = $directory . "/createpdf.bat";
828 $fp = fopen($tmpfile, "wb");
829 fwrite($fp, $cmd . " > $filename.pdf");
832 if (!headers_sent()) {
833 Header('Content-Type: application/pdf');
837 $tmpdir = getUploadFilePath();
838 $s = passthru($cmd . " > $tmpdir/$filename.pdf");
839 $errormsg = "<br />\nGenerated <a href=\"".getUploadDataPath()."$filename.pdf\">Upload:$filename.pdf</a>\n";
844 foreach($outfiles as $f) unlink($f);
847 if (!empty($errormsg)) {
848 $request->discardOutput();
849 $GLOBALS['ErrorManager']->_postponed_errors = array();
853 if (check_php_version(4,1)) {
854 global $ErrorManager;
855 $ErrorManager->popErrorHandler();
858 $WikiTheme->HTML_DUMP_SUFFIX = '';
859 $WikiTheme->DUMP_MODE = false;
860 $WikiTheme->_MoreAttr['body'] = $_bodyAttr;
864 ////////////////////////////////////////////////////////////////
866 // Functions for restoring.
868 ////////////////////////////////////////////////////////////////
870 function SavePage (&$request, &$pageinfo, $source, $filename)
872 static $overwite_all = false;
873 $pagedata = $pageinfo['pagedata']; // Page level meta-data.
874 $versiondata = $pageinfo['versiondata']; // Revision level meta-data.
876 if (empty($pageinfo['pagename'])) {
877 PrintXML(HTML::p(HTML::strong(_("Empty pagename!"))));
881 if (empty($versiondata['author_id']))
882 $versiondata['author_id'] = $versiondata['author'];
884 // remove invalid backend specific chars. utf8 issues mostly
885 $pagename_check = new WikiPagename($pageinfo['pagename']);
886 if (!$pagename_check->isValid()) {
887 PrintXML(HTML::p(HTML::strong(_("Invalid pagename!")." ".$pageinfo['pagename'])));
890 $pagename = $pagename_check->getName();
891 $content = $pageinfo['content'];
893 if ($pagename == _("InterWikiMap"))
894 $content = _tryinsertInterWikiMap($content);
896 $dbi =& $request->_dbi;
897 $page = $dbi->getPage($pagename);
899 // Try to merge if updated pgsrc contents are different. This
900 // whole thing is hackish
902 // TODO: try merge unless:
903 // if (current contents = default contents && pgsrc_version >=
904 // pgsrc_version) then just upgrade this pgsrc
905 $needs_merge = false;
909 if ($request->getArg('merge')) {
912 else if ($request->getArg('overwrite')) {
916 $current = $page->getCurrentRevision();
918 $edit = $request->getArg('edit');
920 if (isset($edit['keep_old'])) {
924 elseif (isset($edit['overwrite'])) {
928 elseif ( $current and (! $current->hasDefaultContents())
929 && ($current->getPackedContent() != $content) )
931 include_once('lib/editpage.php');
932 $request->setArg('pagename', $pagename);
933 $v = $current->getVersion();
934 $request->setArg('revision', $current->getVersion());
935 $p = new LoadFileConflictPageEditor($request);
936 $p->_content = $content;
937 $p->_currentVersion = $v - 1;
938 $p->editPage($saveFailed = true);
939 return; //early return
943 foreach ($pagedata as $key => $value) {
945 $page->set($key, $value);
948 $mesg = HTML::p(array('style' => 'text-indent: 3em;'));
950 $mesg->pushContent(' ', fmt("from %s", $source));
953 //FIXME: This should not happen! (empty vdata, corrupt cache or db)
954 $current = $page->getCurrentRevision();
956 if ($current->getVersion() == 0) {
957 $mesg->pushContent(' - ', _("New page"));
961 if ( (! $current->hasDefaultContents())
962 && ($current->getPackedContent() != $content) ) {
964 $mesg->pushContent(' ',
965 fmt("has edit conflicts - overwriting anyway"));
967 if (substr_count($source, 'pgsrc')) {
968 $versiondata['author'] = _("The PhpWiki programming team");
969 // but leave authorid as userid who loaded the file
973 if (isset($edit['keep_old'])) {
974 $mesg->pushContent(' ', fmt("keep old"));
976 $mesg->pushContent(' ', fmt("has edit conflicts - skipped"));
977 $needs_merge = true; // hackish, to display the buttons
982 else if ($current->getPackedContent() == $content
983 && $current->get('author') == $versiondata['author']) {
984 // The page metadata is already changed, we don't need a new revision.
985 // This was called previously "is identical to current version %d - skipped"
986 // which is wrong, since the pagedata was stored, not skipped.
987 $mesg->pushContent(' ',
988 fmt("content is identical to current version %d - no new revision created",
989 $current->getVersion()));
996 // in case of failures print the culprit:
997 if (!isa($request,'MockRequest')) {
998 PrintXML(HTML::p(WikiLink($pagename))); flush();
1000 $new = $page->save($content, WIKIDB_FORCE_CREATE, $versiondata);
1002 $mesg->pushContent(' ', fmt("- saved to database as version %d",
1003 $new->getVersion()));
1007 // hackish, $source contains needed path+filename
1008 $f = str_replace(sprintf(_("MIME file %s"), ''), '', $f);
1009 $f = str_replace(sprintf(_("Serialized file %s"), ''), '', $f);
1010 $f = str_replace(sprintf(_("plain file %s"), ''), '', $f);
1011 //check if uploaded file? they pass just the content, but the file is gone
1014 $meb = Button(array('action' => 'loadfile',
1018 _("PhpWikiAdministration"),
1020 $owb = Button(array('action' => 'loadfile',
1023 _("Restore Anyway"),
1024 _("PhpWikiAdministration"),
1026 $mesg->pushContent(' ', $meb, " ", $owb);
1027 if (!$overwite_all) {
1028 $args = $request->getArgs();
1029 $args['overwrite'] = 1;
1030 $owb = Button($args,
1032 _("PhpWikiAdministration"),
1034 $mesg->pushContent(HTML::div(array('class' => 'hint'), $owb));
1035 $overwite_all = true;
1038 $mesg->pushContent(HTML::em(_(" Sorry, cannot merge.")));
1042 if (!isa($request,'MockRequest')) {
1044 PrintXML(HTML::p(HTML::em(WikiLink($pagename))), $mesg);
1051 // action=revert (by diff)
1052 function RevertPage (&$request)
1055 $pagename = $request->getArg('pagename');
1056 $version = $request->getArg('version');
1058 PrintXML(HTML::p(fmt("Revert")," ",WikiLink($pagename)),
1059 HTML::p(_("missing required version argument")));
1062 $dbi =& $request->_dbi;
1063 $page = $dbi->getPage($pagename);
1064 $current = $page->getCurrentRevision();
1065 $currversion = $current->getVersion();
1066 if ($currversion == 0) {
1067 $mesg->pushContent(' ', _("no page content"));
1068 PrintXML(HTML::p(fmt("Revert")," ",WikiLink($pagename)),
1073 if ($currversion == $version) {
1074 $mesg->pushContent(' ', _("same version page"));
1075 PrintXML(HTML::p(fmt("Revert")," ",WikiLink($pagename)),
1080 if ($request->getArg('cancel')) {
1081 $mesg->pushContent(' ', _("Cancelled"));
1082 PrintXML(HTML::p(fmt("Revert")," ",WikiLink($pagename)),
1087 if (!$request->getArg('verify')) {
1088 $mesg->pushContent(HTML::br(),
1091 HTML::form(array('action' => $request->getPostURL(),
1092 'method' => 'post'),
1093 HiddenInputs($request->getArgs(), false, array('verify')),
1094 HiddenInputs(array('verify' => 1)),
1095 Button('submit:verify', _("Yes"), 'button'),
1096 HTML::Raw(' '),
1097 Button('submit:cancel', _("Cancel"), 'button')),
1099 $rev = $page->getRevision($version);
1100 $html = HTML(HTML::p(fmt("Revert %s to version $version", WikiLink($pagename))),
1102 $rev->getTransformedContent());
1103 $template = Template('browse',
1104 array('CONTENT' => $html));
1105 GeneratePage($template, $pagename, $rev);
1106 $request->checkValidators();
1110 $rev = $page->getRevision($version);
1111 $content = $rev->getPackedContent();
1112 $versiondata = $rev->_data;
1113 $versiondata['summary'] = sprintf(_("revert to version %d"), $version);
1114 $new = $page->save($content, $currversion + 1, $versiondata);
1117 $pagelink = WikiLink($pagename);
1118 $mesg->pushContent(fmt("Revert: %s", $pagelink),
1119 fmt("- version %d saved to database as version %d",
1120 $version, $new->getVersion()));
1121 // Force browse of current page version.
1122 $request->setArg('version', false);
1123 $template = Template('savepage', array());
1124 $template->replace('CONTENT', $new->getTransformedContent());
1126 GeneratePage($template, $mesg, $new);
1130 function _tryinsertInterWikiMap($content) {
1132 if (strpos($content, "<verbatim>")) {
1133 //$error_html = " The newly loaded pgsrc already contains a verbatim block.";
1136 if (!$goback && !defined('INTERWIKI_MAP_FILE')) {
1137 $error_html = sprintf(" "._("%s: not defined"), "INTERWIKI_MAP_FILE");
1140 $mapfile = FindFile(INTERWIKI_MAP_FILE,1);
1141 if (!$goback && !file_exists($mapfile)) {
1142 $error_html = sprintf(" "._("%s: file not found"), INTERWIKI_MAP_FILE);
1146 if (!empty($error_html))
1147 trigger_error(_("Default InterWiki map file not loaded.")
1148 . $error_html, E_USER_NOTICE);
1152 // if loading from virgin setup do echo, otherwise trigger_error E_USER_NOTICE
1153 if (!isa($GLOBALS['request'], 'MockRequest'))
1154 echo sprintf(_("Loading InterWikiMap from external file %s."), $mapfile),"<br />";
1156 $fd = fopen ($mapfile, "rb");
1157 $data = fread ($fd, filesize($mapfile));
1159 $content = $content . "\n<verbatim>\n$data</verbatim>\n";
1163 function ParseSerializedPage($text, $default_pagename, $user)
1165 if (!preg_match('/^a:\d+:{[si]:\d+/', $text))
1168 $pagehash = unserialize($text);
1170 // Split up pagehash into four parts:
1173 // page-level meta-data
1174 // revision-level meta-data
1176 if (!defined('FLAG_PAGE_LOCKED'))
1177 define('FLAG_PAGE_LOCKED', 1);
1178 $pageinfo = array('pagedata' => array(),
1179 'versiondata' => array());
1181 $pagedata = &$pageinfo['pagedata'];
1182 $versiondata = &$pageinfo['versiondata'];
1184 // Fill in defaults.
1185 if (empty($pagehash['pagename']))
1186 $pagehash['pagename'] = $default_pagename;
1187 if (empty($pagehash['author'])) {
1188 $pagehash['author'] = $user->getId();
1191 foreach ($pagehash as $key => $value) {
1196 $pageinfo[$key] = $value;
1199 $pageinfo[$key] = join("\n", $value);
1202 if (($value & FLAG_PAGE_LOCKED) != 0)
1203 $pagedata['locked'] = 'yes';
1207 $pagedata[$key] = $value;
1211 $pagedata['perm'] = ParseMimeifiedPerm($value);
1213 case 'lastmodified':
1214 $versiondata['mtime'] = $value;
1219 $versiondata[$key] = $value;
1223 if (empty($pagehash['charset']))
1224 $pagehash['charset'] = 'iso-8859-1';
1225 // compare to target charset
1226 if (strtolower($pagehash['charset']) != strtolower($GLOBALS['charset'])) {
1227 $pageinfo['content'] = charset_convert($params['charset'], $GLOBALS['charset'], $pageinfo['content']);
1228 $pageinfo['pagename'] = charset_convert($params['charset'], $GLOBALS['charset'], $pageinfo['pagename']);
1233 function SortByPageVersion ($a, $b) {
1234 return $a['version'] - $b['version'];
1238 * Security alert! We should not allow to import config.ini into our wiki (or from a sister wiki?)
1239 * because the sql passwords are in plaintext there. And the webserver must be able to read it.
1240 * Detected by Santtu Jarvi.
1242 function LoadFile (&$request, $filename, $text = false, $mtime = false)
1244 if (preg_match("/config$/", dirname($filename)) // our or other config
1245 and preg_match("/config.*\.ini/", basename($filename))) // backups and other versions also
1247 trigger_error(sprintf("Refused to load %s", $filename), E_USER_WARNING);
1250 if (!is_string($text)) {
1252 $stat = stat($filename);
1254 $text = implode("", file($filename));
1257 if (! $request->getArg('start_debug')) @set_time_limit(30); // Reset watchdog
1258 else @set_time_limit(240);
1260 // FIXME: basename("filewithnoslashes") seems to return garbage sometimes.
1261 $basename = basename("/dummy/" . $filename);
1264 $mtime = time(); // Last resort.
1266 // DONE: check source - target charset for content and pagename
1267 // but only for pgsrc'ed content, not from the browser.
1269 $default_pagename = rawurldecode($basename);
1270 if ( ($parts = ParseMimeifiedPages($text)) ) {
1271 if (count($parts) > 1)
1272 $overwrite = $request->getArg('overwrite');
1273 usort($parts, 'SortByPageVersion');
1274 foreach ($parts as $pageinfo) {
1276 if (count($parts) > 1)
1277 $request->setArg('overwrite', 1);
1278 SavePage($request, $pageinfo, sprintf(_("MIME file %s"),
1279 $filename), $basename);
1281 if (count($parts) > 1)
1283 $request->setArg('overwrite', $overwrite);
1285 unset($request->_args['overwrite']);
1287 else if ( ($pageinfo = ParseSerializedPage($text, $default_pagename,
1288 $request->getUser())) ) {
1289 SavePage($request, $pageinfo, sprintf(_("Serialized file %s"),
1290 $filename), $basename);
1294 $user = $request->getUser();
1296 $file_charset = 'iso-8859-1';
1297 // compare to target charset
1298 if ($file_charset != strtolower($GLOBALS['charset'])) {
1299 $text = charset_convert($file_charset, $GLOBALS['charset'], $text);
1300 $default_pagename = charset_convert($file_charset, $GLOBALS['charset'], $default_pagename);
1303 // Assume plain text file.
1304 $pageinfo = array('pagename' => $default_pagename,
1305 'pagedata' => array(),
1307 => array('author' => $user->getId()),
1308 'content' => preg_replace('/[ \t\r]*\n/', "\n",
1311 SavePage($request, $pageinfo, sprintf(_("plain file %s"), $filename),
1316 function LoadZip (&$request, $zipfile, $files = false, $exclude = false) {
1317 $zip = new ZipReader($zipfile);
1318 $timeout = (! $request->getArg('start_debug')) ? 20 : 120;
1319 while (list ($fn, $data, $attrib) = $zip->readFile()) {
1320 // FIXME: basename("filewithnoslashes") seems to return
1321 // garbage sometimes.
1322 $fn = basename("/dummy/" . $fn);
1323 if ( ($files && !in_array($fn, $files))
1324 || ($exclude && in_array($fn, $exclude)) ) {
1325 PrintXML(HTML::p(WikiLink($fn)),
1326 HTML::p(_("Skipping")));
1330 longer_timeout($timeout); // longer timeout per page
1331 LoadFile($request, $fn, $data, $attrib['mtime']);
1335 function LoadDir (&$request, $dirname, $files = false, $exclude = false) {
1336 $fileset = new LimitedFileSet($dirname, $files, $exclude);
1338 if (!$files and ($skiplist = $fileset->getSkippedFiles())) {
1339 PrintXML(HTML::p(HTML::strong(_("Skipping"))));
1341 foreach ($skiplist as $file)
1342 $list->pushContent(HTML::li(WikiLink($file)));
1343 PrintXML(HTML::p($list));
1346 // Defer HomePage loading until the end. If anything goes wrong
1347 // the pages can still be loaded again.
1348 $files = $fileset->getFiles();
1349 if (in_array(HOME_PAGE, $files)) {
1350 $files = array_diff($files, array(HOME_PAGE));
1351 $files[] = HOME_PAGE;
1353 $timeout = (! $request->getArg('start_debug')) ? 20 : 120;
1354 foreach ($files as $file) {
1355 longer_timeout($timeout); // longer timeout per page
1356 if (substr($file,-1,1) != '~') // refuse to load backup files
1357 LoadFile($request, "$dirname/$file");
1361 class LimitedFileSet extends FileSet {
1362 function LimitedFileSet($dirname, $_include, $exclude) {
1363 $this->_includefiles = $_include;
1364 $this->_exclude = $exclude;
1365 $this->_skiplist = array();
1366 parent::FileSet($dirname);
1369 function _filenameSelector($fn) {
1370 $incl = &$this->_includefiles;
1371 $excl = &$this->_exclude;
1373 if ( ($incl && !in_array($fn, $incl))
1374 || ($excl && in_array($fn, $excl)) ) {
1375 $this->_skiplist[] = $fn;
1382 function getSkippedFiles () {
1383 return $this->_skiplist;
1388 function IsZipFile ($filename_or_fd)
1390 // See if it looks like zip file
1391 if (is_string($filename_or_fd))
1393 $fd = fopen($filename_or_fd, "rb");
1394 $magic = fread($fd, 4);
1399 $fpos = ftell($filename_or_fd);
1400 $magic = fread($filename_or_fd, 4);
1401 fseek($filename_or_fd, $fpos);
1404 return $magic == ZIP_LOCHEAD_MAGIC || $magic == ZIP_CENTHEAD_MAGIC;
1408 function LoadAny (&$request, $file_or_dir, $files = false, $exclude = false)
1410 // Try urlencoded filename for accented characters.
1411 if (!file_exists($file_or_dir)) {
1412 // Make sure there are slashes first to avoid confusing phps
1413 // with broken dirname or basename functions.
1414 // FIXME: windows uses \ and :
1415 if (is_integer(strpos($file_or_dir, "/"))) {
1416 $newfile = FindFile($file_or_dir, true);
1417 // Panic. urlencoded by the browser (e.g. San%20Diego => San Diego)
1419 $file_or_dir = dirname($file_or_dir) . "/"
1420 . rawurlencode(basename($file_or_dir));
1422 // This is probably just a file.
1423 $file_or_dir = rawurlencode($file_or_dir);
1427 $type = filetype($file_or_dir);
1428 if ($type == 'link') {
1429 // For symbolic links, use stat() to determine
1430 // the type of the underlying file.
1431 list(,,$mode) = stat($file_or_dir);
1432 $type = ($mode >> 12) & 017;
1435 elseif ($type == 004)
1440 $request->finish(fmt("Empty or not existing source. Unable to load: %s", $file_or_dir));
1442 else if ($type == 'dir') {
1443 LoadDir($request, $file_or_dir, $files, $exclude);
1445 else if ($type != 'file' && !preg_match('/^(http|ftp):/', $file_or_dir))
1447 $request->finish(fmt("Bad file type: %s", $type));
1449 else if (IsZipFile($file_or_dir)) {
1450 LoadZip($request, $file_or_dir, $files, $exclude);
1452 else /* if (!$files || in_array(basename($file_or_dir), $files)) */
1454 LoadFile($request, $file_or_dir);
1458 function LoadFileOrDir (&$request)
1460 $source = $request->getArg('source');
1461 $finder = new FileFinder;
1462 $source = $finder->slashifyPath($source);
1463 $page = rawurldecode(basename($source));
1464 StartLoadDump($request, fmt("Loading '%s'",
1465 HTML(dirname($source),
1466 dirname($source) ? "/" : "",
1467 WikiLink($page,'auto'))));
1469 LoadAny($request, $source);
1471 EndLoadDump($request);
1475 * HomePage was not found so first-time install is supposed to run.
1476 * - import all pgsrc pages.
1477 * - Todo: installer interface to edit config/config.ini settings
1478 * - Todo: ask for existing old index.php to convert to config/config.ini
1479 * - Todo: theme-specific pages:
1480 * blog - HomePage, ADMIN_USER/Blogs
1482 function SetupWiki (&$request)
1484 global $GenericPages, $LANG;
1486 //FIXME: This is a hack (err, "interim solution")
1487 // This is a bogo-bogo-login: Login without
1488 // saving login information in session state.
1489 // This avoids logging in the unsuspecting
1490 // visitor as "The PhpWiki programming team".
1492 // This really needs to be cleaned up...
1493 // (I'm working on it.)
1494 $real_user = $request->_user;
1495 if (ENABLE_USER_NEW)
1496 $request->_user = new _BogoUser(_("The PhpWiki programming team"));
1499 $request->_user = new WikiUser($request, _("The PhpWiki programming team"),
1502 StartLoadDump($request, _("Loading up virgin wiki"));
1504 $pgsrc = FindLocalizedFile(WIKI_PGSRC);
1505 $default_pgsrc = FindFile(DEFAULT_WIKI_PGSRC);
1507 $request->setArg('overwrite', true);
1508 if ($default_pgsrc != $pgsrc) {
1509 LoadAny($request, $default_pgsrc, $GenericPages);
1511 $request->setArg('overwrite', false);
1512 LoadAny($request, $pgsrc);
1513 $dbi =& $request->_dbi;
1515 // Ensure that all mandatory pages are loaded
1516 $finder = new FileFinder;
1517 foreach (array_merge(explode(':','Help/OldTextFormattingRules:Help/TextFormattingRules:PhpWikiAdministration'),
1518 $GLOBALS['AllActionPages'],
1519 array(constant('HOME_PAGE'))) as $f)
1521 $page = gettext($f);
1522 $epage = urlencode($page);
1523 if (! $dbi->isWikiPage($page) ) {
1524 // translated version provided?
1525 if ($lf = FindLocalizedFile($pgsrc . $finder->_pathsep . $epage, 1)) {
1526 LoadAny($request, $lf);
1527 } else { // load english version of required action page
1528 LoadAny($request, FindFile(DEFAULT_WIKI_PGSRC . $finder->_pathsep . urlencode($f)));
1532 if (! $dbi->isWikiPage($page)) {
1533 trigger_error(sprintf("Mandatory file %s couldn't be loaded!", $page),
1538 $pagename = _("InterWikiMap");
1539 $map = $dbi->getPage($pagename);
1540 $map->set('locked', true);
1541 PrintXML(HTML::p(HTML::em(WikiLink($pagename)), HTML::strong(" locked")));
1542 EndLoadDump($request);
1545 function LoadPostFile (&$request)
1547 $upload = $request->getUploadedFile('file');
1550 $request->finish(_("No uploaded file to upload?")); // FIXME: more concise message
1553 // Dump http headers.
1554 StartLoadDump($request, sprintf(_("Uploading %s"), $upload->getName()));
1557 $fd = $upload->open();
1559 LoadZip($request, $fd, false, array(_("RecentChanges")));
1561 LoadFile($request, $upload->getName(), $upload->getContents());
1564 EndLoadDump($request);
1568 $Log: not supported by cvs2svn $
1569 Revision 1.159 2008/03/17 19:41:06 rurban
1570 Windows quirks: Since dumps needs to be copied, we have to disallow "bla " dirs for all platforms.
1572 Revision 1.158 2008/02/14 18:36:52 rurban
1575 Revision 1.157 2007/09/19 18:01:27 rurban
1576 better pageset detection: format=
1578 Revision 1.156 2007/09/15 12:32:50 rurban
1579 Improve multi-page format handling: abstract _DumpHtmlToDir. get rid of non-external pdf, non-global VALID_LINKS
1581 Revision 1.155 2007/09/12 19:40:41 rurban
1582 Copy locally uploaded images also
1584 Revision 1.154 2007/08/10 22:00:43 rurban
1586 We have to apply a different "/" logic for dumpserial, htmldump and
1587 zipdump. dirs are allowed for zipdump and htmldump, not for dumpserial.
1589 Revision 1.153 2007/05/28 20:54:40 rurban
1590 fix DumpToHtml creating dirs
1592 Revision 1.152 2007/05/01 16:22:41 rurban
1593 lock InterWikiMap on init
1595 Revision 1.151 2007/02/17 14:17:34 rurban
1596 only media=print css for htmldump and pdf
1598 Revision 1.150 2007/01/20 15:53:42 rurban
1599 Use WikiPagename treatment for imported pagenames
1601 Revision 1.149 2007/01/03 21:25:10 rurban
1602 Use convert_charset()
1604 Revision 1.148 2007/01/02 13:21:57 rurban
1605 omit want_content if not necessary. support keep_old and overwrite buttons
1607 Revision 1.147 2006/12/22 17:44:15 rurban
1608 support importing foreign charsets. e.g latin1 => utf8
1610 Revision 1.146 2006/12/17 18:35:23 rurban
1611 Create the right subdirectory name, urlencoded.
1613 Revision 1.145 2006/09/06 06:01:18 rurban
1614 support loadfile multipart archives automatically
1616 Revision 1.144 2006/08/25 22:06:13 rurban
1617 args fix to pass $args to the template
1619 Revision 1.143 2006/08/25 21:48:39 rurban
1622 Revision 1.142 2006/03/19 17:16:32 rurban
1623 remove remaining cruft
1625 Revision 1.141 2006/03/19 17:11:32 rurban
1626 add verify to RevertPage, display reverted page as template
1628 Revision 1.140 2006/03/07 20:45:43 rurban
1629 wikihash for php-5.1
1631 Revision 1.139 2005/08/27 18:02:43 rurban
1632 fix and expand pages
1634 Revision 1.138 2005/08/27 09:39:10 rurban
1635 dumphtml when not at admin page: dump the current or given page
1637 Revision 1.137 2005/01/30 23:14:38 rurban
1640 Revision 1.136 2005/01/25 07:07:24 rurban
1641 remove body tags in html dumps, add css and images to zipdumps, simplify printing
1643 Revision 1.135 2004/12/26 17:17:25 rurban
1644 announce dumps - mult.requests to avoid request::finish, e.g. LinkDatabase, PdfOut, ...
1646 Revision 1.134 2004/12/20 16:05:01 rurban
1647 gettext msg unification
1649 Revision 1.133 2004/12/08 12:57:41 rurban
1650 page-specific timeouts for long multi-page requests
1652 Revision 1.132 2004/12/08 01:18:33 rurban
1653 Disallow loading config*.ini files. Detected by Santtu Jarvi.
1655 Revision 1.131 2004/11/30 17:48:38 rurban
1658 Revision 1.130 2004/11/25 08:28:12 rurban
1659 dont fatal on missing css or imgfiles and actually print the miss
1661 Revision 1.129 2004/11/25 08:11:40 rurban
1662 pass exclude to the get_all_pages backend
1664 Revision 1.128 2004/11/16 16:16:44 rurban
1665 enable Overwrite All for upgrade
1667 Revision 1.127 2004/11/01 10:43:57 rurban
1668 seperate PassUser methods into seperate dir (memory usage)
1669 fix WikiUser (old) overlarge data session
1670 remove wikidb arg from various page class methods, use global ->_dbi instead
1673 Revision 1.126 2004/10/16 15:13:39 rurban
1674 new [Overwrite All] button
1676 Revision 1.125 2004/10/14 19:19:33 rurban
1677 loadsave: check if the dumped file will be accessible from outside.
1678 and some other minor fixes. (cvsclient native not yet ready)
1680 Revision 1.124 2004/10/04 23:44:28 rurban
1681 for older or CGI phps
1683 Revision 1.123 2004/09/25 16:26:54 rurban
1684 deferr notifies (to be improved)
1686 Revision 1.122 2004/09/17 14:25:45 rurban
1689 Revision 1.121 2004/09/08 13:38:00 rurban
1690 improve loadfile stability by using markup=2 as default for undefined markup-style.
1691 use more refs for huge objects.
1692 fix debug=static issue in WikiPluginCached
1694 Revision 1.120 2004/07/08 19:04:42 rurban
1695 more unittest fixes (file backend, metadata RatingsDb)
1697 Revision 1.119 2004/07/08 15:23:59 rurban
1698 less verbose for tests
1700 Revision 1.118 2004/07/08 13:50:32 rurban
1701 various unit test fixes: print error backtrace on _DEBUG_TRACE; allusers fix; new PHPWIKI_NOMAIN constant for omitting the mainloop
1703 Revision 1.117 2004/07/02 09:55:58 rurban
1704 more stability fixes: new DISABLE_GETIMAGESIZE if your php crashes when loading LinkIcons: failing getimagesize in old phps; blockparser stabilized
1706 Revision 1.116 2004/07/01 09:05:41 rurban
1707 support pages and exclude arguments for all 4 dump methods
1709 Revision 1.115 2004/07/01 08:51:22 rurban
1710 dumphtml: added exclude, print pagename before processing
1712 Revision 1.114 2004/06/28 12:51:41 rurban
1713 improved dumphtml and virgin setup
1715 Revision 1.113 2004/06/27 10:26:02 rurban
1716 oci8 patch by Philippe Vanhaesendonck + some ADODB notes+fixes
1718 Revision 1.112 2004/06/25 14:29:20 rurban
1719 WikiGroup refactoring:
1720 global group attached to user, code for not_current user.
1721 improved helpers for special groups (avoid double invocations)
1722 new experimental config option ENABLE_XHTML_XML (fails with IE, and document.write())
1723 fixed a XHTML validation error on userprefs.tmpl
1725 Revision 1.111 2004/06/21 16:38:55 rurban
1726 fixed the StartLoadDump html argument hack.
1728 Revision 1.110 2004/06/21 16:22:30 rurban
1729 add DEFAULT_DUMP_DIR and HTML_DUMP_DIR constants, for easier cmdline dumps,
1730 fixed dumping buttons locally (images/buttons/),
1731 support pages arg for dumphtml,
1732 optional directory arg for dumpserial + dumphtml,
1733 fix a AllPages warning,
1734 show dump warnings/errors on DEBUG,
1735 don't warn just ignore on wikilens pagelist columns, if not loaded.
1736 RateIt pagelist column is called "rating", not "ratingwidget" (Dan?)
1738 Revision 1.109 2004/06/17 11:31:05 rurban
1739 jump back to label after dump/upgrade
1741 Revision 1.108 2004/06/16 12:43:01 rurban
1742 4.0.6 cannot use this errorhandler (not found)
1744 Revision 1.107 2004/06/14 11:31:37 rurban
1745 renamed global $Theme to $WikiTheme (gforge nameclash)
1746 inherit PageList default options from PageList
1747 default sortby=pagename
1748 use options in PageList_Selectable (limit, sortby, ...)
1749 added action revert, with button at action=diff
1750 added option regex to WikiAdminSearchReplace
1752 Revision 1.106 2004/06/13 13:54:25 rurban
1753 Catch fatals on the four dump calls (as file and zip, as html and mimified)
1754 FoafViewer: Check against external requirements, instead of fatal.
1755 Change output for xhtmldumps: using file:// urls to the local fs.
1756 Catch SOAP fatal by checking for GOOGLE_LICENSE_KEY
1757 Import GOOGLE_LICENSE_KEY and FORTUNE_DIR from config.ini.
1759 Revision 1.105 2004/06/08 19:48:16 rurban
1760 fixed foreign setup: no ugly skipped msg for the GenericPages, load english actionpages if translated not found
1762 Revision 1.104 2004/06/08 13:51:57 rurban
1765 Revision 1.103 2004/06/08 10:54:46 rurban
1766 better acl dump representation, read back acl and owner
1768 Revision 1.102 2004/06/06 16:58:51 rurban
1769 added more required ActionPages for foreign languages
1770 install now english ActionPages if no localized are found. (again)
1771 fixed default anon user level to be 0, instead of -1
1772 (wrong "required administrator to view this page"...)
1774 Revision 1.101 2004/06/04 20:32:53 rurban
1775 Several locale related improvements suggested by Pierrick Meignen
1776 LDAP fix by John Cole
1777 reenable admin check without ENABLE_PAGEPERM in the admin plugins
1779 Revision 1.100 2004/05/02 21:26:38 rurban
1780 limit user session data (HomePageHandle and auth_dbi have to invalidated anyway)
1781 because they will not survive db sessions, if too large.
1782 extended action=upgrade
1783 some WikiTranslation button work
1784 revert WIKIAUTH_UNOBTAINABLE (need it for main.php)
1785 some temp. session debug statements
1787 Revision 1.99 2004/05/02 15:10:07 rurban
1788 new finally reliable way to detect if /index.php is called directly
1789 and if to include lib/main.php
1790 new global AllActionPages
1791 SetupWiki now loads all mandatory pages: HOME_PAGE, action pages, and warns if not.
1792 WikiTranslation what=buttons for Carsten to create the missing MacOSX buttons
1793 PageGroupTestOne => subpages
1794 renamed PhpWikiRss to PhpWikiRecentChanges
1795 more docs, default configs, ...
1797 Revision 1.98 2004/04/29 23:25:12 rurban
1798 re-ordered locale init (as in 1.3.9)
1799 fixed loadfile with subpages, and merge/restore anyway
1800 (sf.net bug #844188)
1802 Revision 1.96 2004/04/19 23:13:03 zorloc
1803 Connect the rest of PhpWiki to the IniConfig system. Also the keyword regular expression is not a config setting
1805 Revision 1.95 2004/04/18 01:11:52 rurban
1806 more numeric pagename fixes.
1807 fixed action=upload with merge conflict warnings.
1808 charset changed from constant to global (dynamic utf-8 switching)
1810 Revision 1.94 2004/03/14 16:36:37 rurban
1811 dont load backup files
1813 Revision 1.93 2004/02/26 03:22:05 rurban
1814 also copy css and images with XHTML Dump
1816 Revision 1.92 2004/02/26 02:25:54 rurban
1817 fix empty and #-anchored links in XHTML Dumps
1819 Revision 1.91 2004/02/24 17:19:37 rurban
1820 debugging helpers only
1822 Revision 1.90 2004/02/24 17:09:24 rurban
1823 fixed \r\r\n with dumping on windows
1825 Revision 1.88 2004/02/22 23:20:31 rurban
1826 fixed DumpHtmlToDir,
1827 enhanced sortby handling in PageList
1828 new button_heading th style (enabled),
1829 added sortby and limit support to the db backends and plugins
1830 for paging support (<<prev, next>> links on long lists)
1832 Revision 1.87 2004/01/26 09:17:49 rurban
1833 * changed stored pref representation as before.
1834 the array of objects is 1) bigger and 2)
1835 less portable. If we would import packed pref
1836 objects and the object definition was changed, PHP would fail.
1837 This doesn't happen with an simple array of non-default values.
1838 * use $prefs->retrieve and $prefs->store methods, where retrieve
1839 understands the interim format of array of objects also.
1840 * simplified $prefs->get() and fixed $prefs->set()
1841 * added $user->_userid and class '_WikiUser' portability functions
1842 * fixed $user object ->_level upgrading, mostly using sessions.
1843 this fixes yesterdays problems with loosing authorization level.
1844 * fixed WikiUserNew::checkPass to return the _level
1845 * fixed WikiUserNew::isSignedIn
1846 * added explodePageList to class PageList, support sortby arg
1847 * fixed UserPreferences for WikiUserNew
1848 * fixed WikiPlugin for empty defaults array
1849 * UnfoldSubpages: added pagename arg, renamed pages arg,
1850 removed sort arg, support sortby arg
1852 Revision 1.86 2003/12/02 16:18:26 carstenklapp
1853 Minor enhancement: Provide more meaningful filenames for WikiDB zip
1856 Revision 1.85 2003/11/30 18:18:13 carstenklapp
1857 Minor code optimization: use include_once instead of require_once
1858 inside functions that might not always called.
1860 Revision 1.84 2003/11/26 20:47:47 carstenklapp
1861 Redo bugfix: My last refactoring broke merge-edit & overwrite
1862 functionality again, should be fixed now. Sorry.
1864 Revision 1.83 2003/11/20 22:18:54 carstenklapp
1865 New feature: h1 during merge-edit displays WikiLink to original page.
1866 Internal changes: Replaced some hackish url-generation code in
1867 function SavePage (for pgsrc merge-edit) with appropriate Button()
1870 Revision 1.82 2003/11/18 19:48:01 carstenklapp
1871 Fixed missing gettext _() for button name.
1873 Revision 1.81 2003/11/18 18:28:35 carstenklapp
1874 Bugfix: In the Load File function of PhpWikiAdministration: When doing
1875 a "Merge Edit" or "Restore Anyway", page names containing accented
1876 letters (such as locale/de/pgsrc/G%E4steBuch) would produce a file not
1877 found error (Use FilenameForPage funtion to urlencode page names).
1879 Revision 1.80 2003/03/07 02:46:57 dairiki
1880 Omit checks for safe_mode before set_time_limit(). Just prefix the
1881 set_time_limit() calls with @ so that they fail silently if not
1884 Revision 1.79 2003/02/26 01:56:05 dairiki
1885 Only zip pages with legal pagenames.
1887 Revision 1.78 2003/02/24 02:05:43 dairiki
1888 Fix "n bytes written" message when dumping HTML.
1890 Revision 1.77 2003/02/21 04:12:05 dairiki
1891 Minor fixes for new cached markup.
1893 Revision 1.76 2003/02/16 19:47:17 dairiki
1894 Update WikiDB timestamp when editing or deleting pages.
1896 Revision 1.75 2003/02/15 03:04:30 dairiki
1897 Fix for WikiUser constructor API change.
1899 Revision 1.74 2003/02/15 02:18:04 dairiki
1900 When default language was English (at least), pgsrc was being
1903 LimitedFileSet: Fix typo/bug. ($include was being ignored.)
1905 SetupWiki(): Fix bugs in loading of $GenericPages.
1907 Revision 1.73 2003/01/28 21:09:17 zorloc
1908 The get_cfg_var() function should only be used when one is
1909 interested in the value from php.ini or similar. Use ini_get()
1910 instead to get the effective value of a configuration variable.
1913 Revision 1.72 2003/01/03 22:25:53 carstenklapp
1914 Cosmetic fix to "Merge Edit" & "Overwrite" buttons. Added "The PhpWiki
1915 programming team" as author when loading from pgsrc. Source
1918 Revision 1.71 2003/01/03 02:48:05 carstenklapp
1919 function SavePage: Added loadfile options for overwriting or merge &
1920 compare a loaded pgsrc file with an existing page.
1922 function LoadAny: Added a general error message when unable to load a
1923 file instead of defaulting to "Bad file type".
1931 // c-basic-offset: 4
1932 // c-hanging-comment-ender-p: nil
1933 // indent-tabs-mode: nil