<?php if (!defined('PmWiki')) exit(); /* XMLPageStore Copyright 2011-2021 Anomen (ludek_h@seznam.cz) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ $RecipeInfo['XMLPageStore']['Version'] = '2021-10-28'; SDV($EnablePageStoreXML,false); class XMLPageStore extends PageStore { function getNonEmpty($arr, $index1, $index2 = null) { if (isset($arr[$index1])){ if (isset($index2)) { if (isset($arr[$index1][$index2])) { return $arr[$index1][$index2]; } } else { return $arr[$index1]; } } return null; } function read_xml($data, $since=0) { global $Charset; $p = xml_parser_create(); xml_parser_set_option($p,XML_OPTION_CASE_FOLDING, false); xml_parser_set_option($p,XML_OPTION_TARGET_ENCODING, $Charset); # bug http://bugs.php.net/bug.php?id=33240 # xml_parser_set_option($p,XML_OPTION_SKIP_WHITE, true); xml_parse_into_struct($p, $data, $vals, $index); foreach($vals as $v) { if (($v['type'] == 'complete') && ($v['level'] == 2)) { $k = $this->getNonEmpty($v, 'tag'); $t = $this->getNonEmpty($v, 'attributes', 'time'); $p = $this->getNonEmpty($v, 'attributes', 'prev'); if (!empty($t)) { if ($since > 0 && $t < $since) { continue; } $k = "$k:$t"; } if (!empty($p)) { $k = "$k:$p:"; } $page[$k] = $this->getNonEmpty($v,'value'); } } return @$page; } function read($pagename, $since=0) { $pagefile = $this->pagefile($pagename); if ($pagefile && ($fp=@fopen($pagefile, "r"))) { while (!feof($fp)) { $line = fgets($fp, 512); $isXML = (substr($line,0,5) == '<?xml') || (substr(ltrim($line),0,5) == '<page'); if (trim($line) != '') { break; // we found non-empty line } } if ($isXML) { fseek($fp, 0, SEEK_SET); $pagefilesize = filesize($pagefile); $data = fread($fp, $pagefilesize); @fclose($fp); return $this->read_xml($data, $since); } else { @fclose($fp); return parent::read($pagename,$page); } } } function write($pagename,$page) { global $EnablePageStoreXML; ($EnablePageStoreXML == true) ? $this->write_xml($pagename,$page) : parent::write($pagename,$page); } function write_xml($pagename,$page) { global $Now, $Version, $Charset; $page['name'] = $pagename; $page['time'] = $Now; $page['host'] = $_SERVER['REMOTE_ADDR']; $page['agent'] = @$_SERVER['HTTP_USER_AGENT']; $page['rev'] = @$page['rev']+1; unset($page['version']); unset($page['newline']); uksort($page, 'CmpPageAttr'); $s = false; $pagefile = $this->pagefile($pagename); $dir = dirname($pagefile); mkdirp($dir); if ($pagefile && ($fp=fopen("$pagefile,new","w"))) { $x = "<?xml version=\"1.0\" encoding=\"$Charset\"?>\n<page xmlns=\"http://www.pmwiki.org/cookbook/xmlpage\" version=\"$Version\">\n"; $s = true && fputs($fp, $x); $sz = strlen($x); foreach($page as $k=>$v) if ($k > '' && $k[0] != '=') { $v = htmlspecialchars($v, ENT_NOQUOTES, $Charset); if (preg_match("/^([a-z]+)(?::(\d+))(?::(\d+):)?$/", $k, $m)) { $p = empty($m[3]) ? "" : " prev=\"${m[3]}\""; $x = "<${m[1]} time=\"${m[2]}\"$p>$v</${m[1]}>\n"; } else { $x = "<$k>$v</$k>\n"; } $s = $s && fputs($fp, $x); $sz += strlen($x); } $x = "</page>\n"; $s = $s && fputs($fp, $x); $sz += strlen($x); $s = fclose($fp) && $s; $s = $s && (filesize("$pagefile,new") > $sz * 0.95); if (file_exists($pagefile)) $s = $s && unlink($pagefile); $s = $s && rename("$pagefile,new", $pagefile); } $s && fixperms($pagefile); if (!$s) Abort("Cannot write page to $pagename ($pagefile)...changes not saved"); PCache($pagename, $page); } } function ConvertXML() { global $WikiDir; global $EnablePageStoreXML; $pagelist = $WikiDir->ls(); $pagelist = array_unique($pagelist); sort($pagelist); $pagecount = count($pagelist); echo " <html> <head> <title>Convert pages from/to XML</title> </head> <body> <h2>Convert existing pages</h2> <p>I'm now converting "; echo ($EnablePageStoreXML) ? "<b>to</b> " : "<b>from</b> "; echo "XML the files (pages) you have stored in your wiki. When this is finished you can get rid of the <tt>ConvertXML();</tt> line in your local/config.php</p>"; if ($pagelist) { foreach($pagelist as $p) { echo ($EnablePageStoreXML) ? "<li>Converting to XML: $p</li>\n" : "<li>Converting from XML: $p</li>\n"; $page = ReadPage($p); WritePage($p,$page); } } echo "<p>Converted $pagecount pages.</p>\n"; echo "<p>Now you can get rid of the <tt>ConvertXML();</tt> line in your local/config.php</p> </body></html>\n"; exit(0); }