<?php
|
|
|
|
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
|
|
//
|
|
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
|
|
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
|
|
// $Id$
|
|
|
|
|
|
// This defines the XmlLib class, which takes care of import and export of wiki pages and structures
|
|
// from/to a Zip file. The Zip file contains the file "wiki.xml" file, which describes the pages and
|
|
// structures in the Zip archive. For every page, there is a directory with the same name as the
|
|
// page. This directory contains the page itself and the page history.
|
|
//
|
|
// For the export, the export_pages() method generates the Zip file. It calls export_page() in turn.
|
|
// The wiki.xml part for one page is generated by using the Smarty template
|
|
// "tiki-export_page_xml.tpl", which includes "tiki-export_comment_xml.tpl" (for wiki page
|
|
// comments).
|
|
//
|
|
// For the import, the import_pages() method opens the Zip file, parses the wiki.xml file and
|
|
// creates the pages by calling create_page() for each page. The parser (page_Parser) is defined
|
|
// below. It extends the XML_Parser class. create_page() either creates a new page or updates an old
|
|
// one. In the latter case, the page is extended by such things as the attachments or page history.
|
|
|
|
|
|
//this script may only be included - so its better to die if called directly.
|
|
if (strpos($_SERVER['SCRIPT_NAME'], basename(__FILE__)) !== false) {
|
|
header('location: index.php');
|
|
exit;
|
|
}
|
|
define('WIKI_XML', 'wiki.xml');
|
|
|
|
class XmlLib extends TikiLib
|
|
{
|
|
public $errors = [];
|
|
public $errorsArgs = [];
|
|
public $xml = ''; // The contents of the wiki.xml file, which is being generated
|
|
public $zip = ''; // The ZipArchive object
|
|
public $config = ['comments' => true,
|
|
'attachments' => true,
|
|
'history' => true,
|
|
'images' => true,
|
|
'debug' => false];
|
|
public $structureStack = [];
|
|
|
|
public function get_error()
|
|
{
|
|
$str = '';
|
|
foreach ($this->errors as $i => $error) {
|
|
$str = $error;
|
|
if (is_array($this->errorsArgs[$i])) {
|
|
$str .= ': ' . implode(', ', $this->errorsArgs[$i]);
|
|
} else {
|
|
$str .= ': ' . $this->errorsArgs[$i];
|
|
}
|
|
}
|
|
return $str;
|
|
}
|
|
|
|
// Export a list of pages and/or a structure. This creates the Zip file which encompasses the
|
|
// exported pages, the exported images, the exported structure and the wiki.xml file.
|
|
public function export_pages(
|
|
$pages = null, // Array of the names of the pages which should be exported,
|
|
// if any
|
|
$structure = null, // Name of the structure to be exported, if any
|
|
$zipFile = 'dump/xml.zip', // Name of the temporary Zip file, which is being generated
|
|
$config = null) // Configuration (see the $config property, above). Overrides
|
|
// the default configuration (above)
|
|
{
|
|
// Setup the Zip archive, which is to be generated
|
|
if (! class_exists('ZipArchive')) {
|
|
$this->errors[] = 'Problem zip initialisation';
|
|
$this->errorsArgs[] = 'ZipArchive class not found';
|
|
return false;
|
|
}
|
|
|
|
$this->zip = new ZipArchive();
|
|
|
|
if (! $this->zip->open($zipFile, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)) {
|
|
$this->errors[] = 'The file cannot be opened';
|
|
$this->errorsArgs[] = $zipFile;
|
|
return false;
|
|
}
|
|
|
|
if (! empty($config)) {
|
|
$this->config = array_merge($this->config, $config);
|
|
}
|
|
|
|
// Start the wiki.xml file
|
|
$this->xml .= '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
|
|
|
// Export pages, if any
|
|
if (count($pages) >= 1) {
|
|
$this->xml .= "<pages>\n";
|
|
foreach ($pages as $page) {
|
|
if (! $this->export_page($page)) {
|
|
return false;
|
|
}
|
|
}
|
|
$this->xml .= "</pages>\n";
|
|
}
|
|
|
|
// Export structure, if one is specified
|
|
if (! empty($structure)) {
|
|
$structlib = TikiLib::lib('struct');
|
|
$pages = $structlib->s_get_structure_pages($structure);
|
|
$stack = [];
|
|
foreach ($pages as $page) {
|
|
while (count($stack) && $stack[count($stack) - 1] != $page['parent_id']) {
|
|
array_pop($stack);
|
|
$this->xml .= "</structure>\n";
|
|
}
|
|
$this->xml .= "<structure>\n";
|
|
$stack[] = $page['page_ref_id'];
|
|
if (! $this->export_page($page['pageName'])) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
while (count($stack)) {
|
|
array_pop($stack);
|
|
$this->xml .= "</structure>\n";
|
|
}
|
|
}
|
|
|
|
// Add the wiki.xml file and finish the Zip file.
|
|
if (! $this->zip->addFromString(WIKI_XML, $this->xml)) {
|
|
$this->errors[] = 'Can not add the xml';
|
|
$this->errorsArgs[] = WIKI_XML;
|
|
return false;
|
|
}
|
|
if ($this->config['debug']) {
|
|
echo '<pre>' . htmlspecialchars($this->xml) . '</pre>';
|
|
}
|
|
$this->zip->close();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// Export one page. This adds the necessary files to the Zip file and adds the part for the page
|
|
// to the wiki.xml file (in the $xml member variable).
|
|
public function export_page($page)
|
|
{
|
|
global $prefs, $tikidomain;
|
|
$tikilib = TikiLib::lib('tiki');
|
|
$smarty = TikiLib::lib('smarty');
|
|
$parserlib = TikiLib::lib('parser');
|
|
|
|
$dir = $page; // The directory inside the Zip file, which contains the page
|
|
|
|
// Get all the page information from the database. This includes meta data and the page
|
|
// content itself (in the attribute 'data'). $info is extended by the "zip" property and
|
|
// passed to Smarty, for writing all the needed meta data to the wiki.xml file. The 'zip'
|
|
// property is the file name of the page data inside the Zip file.
|
|
$info = $tikilib->get_page_info($page);
|
|
if (empty($info)) {
|
|
$this->errors[] = 'Page does not exist';
|
|
$this->errorsArgs[] = $page;
|
|
return false;
|
|
}
|
|
|
|
$info['zip'] = "$dir/" . $page;
|
|
$smarty->assign_by_ref('info', $info);
|
|
|
|
|
|
// Add the page itself to the Zip file.
|
|
if (! $this->zip->addFromString($info['zip'], $info['data'])) {
|
|
$this->errors[] = 'Can not add the page';
|
|
$this->errorsArgs[] = $info['zip'];
|
|
return false;
|
|
}
|
|
|
|
|
|
// Add the Wiki Comments, if this feature is enabled.
|
|
|
|
if ($prefs['feature_wiki_comments'] == 'y' && $this->config['comments']) {
|
|
$commentslib = TikiLib::lib('comments');
|
|
$comments = $commentslib->get_comments('wiki page:' . $page, 0, 0, 0, 'commentDate_asc', '', 0, 'commentStyle_plain');
|
|
if (! empty($comments['cant'])) {
|
|
$smarty->assign_by_ref('comments', $comments['data']);
|
|
}
|
|
}
|
|
|
|
|
|
// Add the images to the Zip file and assign the metadata to the 'images' Smarty variable.
|
|
// The meta data for each image is an associative array with these parameters:
|
|
// 'filename': The base name of the image file (without path part). This is used only for a
|
|
// file in the "img/wiki_up" directory.
|
|
// 'where': 'wiki' for a file in the "img/wiki_up" directory, or
|
|
// 'fgal' for a file in a file gallery
|
|
// 'zip': The relative path to the image inside of the Zip file
|
|
// 'wiki': The 'src' parameter of the Img plugin. This is for images specified by an URL.
|
|
|
|
$images = [];
|
|
|
|
if (
|
|
$prefs['feature_wiki_pictures'] == 'y'
|
|
&& $this->config['images']
|
|
|
|
// Get all the occurences of "{img...}" in the page.
|
|
&& preg_match_all('/\{img\s*\(?([^\}]+)\)?\s*\}/i', $info['data'], $matches)
|
|
) {
|
|
global $tikiroot;
|
|
|
|
// Iterate over all the occurences of "{img...}".
|
|
foreach ($matches[1] as $match) {
|
|
// $match: The parameters for the img plugin as one string
|
|
// $args: associative array of the arguments for the img plugin
|
|
$args = $parserlib->plugin_split_args($match);
|
|
|
|
// An image specified va "src" (an URL) pointing into the img/wiki_up directory
|
|
if (! empty($args['src']) && preg_match('|img/wiki_up/(.*)|', $args['src'], $m)) {
|
|
$file = empty($tikidomain) ?
|
|
$args['src'] :
|
|
str_replace('img/wiki_up/', "img/wiki_up/$tikidomain/", $args['src']);
|
|
$image = ['filename' => $m[1],
|
|
'where' => 'wiki',
|
|
'zip' => "$dir/images/wiki/" . $m[1],
|
|
'wiki' => $args['src']];
|
|
if (! $this->zip->addFile($file, $image['zip'])) {
|
|
$this->errors[] = 'Can not add the image ';
|
|
$this->errorsArgs[] = $file;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// An image in an image gallery. No longer supported in Tiki 23 and not supported here as well.
|
|
/*elseif (! empty($args['src']) && preg_match('|show_image.php\?(.*)|', $args['src'], $m)) {
|
|
// TODO ImageGalleryRemoval23.x - replace with tiki.file.imageid fileId
|
|
}*/
|
|
|
|
// An image specified via "src" (an URL) in a file gallery (pointing to
|
|
// tiki-download_file.php).
|
|
elseif (! empty($args['src']) && preg_match('|tiki-download_file.php\?(.*)|', $args['src'], $m)) {
|
|
if (($i = strpos($args['src'], 'tiki-download_file.php')) > 0) {
|
|
$path = $_SERVER['HTTP_HOST'] . $tikiroot . substr($args['src'], $i);
|
|
} else {
|
|
$path = $_SERVER['HTTP_HOST'] . $tikiroot . $args['src'];
|
|
}
|
|
|
|
$img = $this->httprequest($path);
|
|
parse_str($m[1], $p);
|
|
$image = ['where' => 'fgal',
|
|
'zip' => "$dir/images/fgal/" . $p['fileId'],
|
|
'wiki' => $args['src']];
|
|
|
|
if (! $this->zip->addFromString($image['zip'], $img)) {
|
|
$this->errors[] = 'Can not add the image';
|
|
$this->errorsArgs[] = $m[1];
|
|
return false;
|
|
}
|
|
} /* else no idea where the img comes from - suppose there are outside tw */
|
|
|
|
$images[] = $image;
|
|
}
|
|
}
|
|
|
|
$smarty->assign_by_ref('images', $images);
|
|
|
|
|
|
// Deal with attachments to the wiki page.
|
|
|
|
if ($prefs['feature_wiki_attachments'] == 'y' && $this->config['attachments']) {
|
|
$wikilib = TikiLib::lib('wiki');
|
|
$attachments = $wikilib->list_wiki_attachments($page, 0, -1);
|
|
if (! empty($attachments['cant'])) {
|
|
foreach ($attachments['data'] as $key => $att) {
|
|
$att_info = $wikilib->get_item_attachment($att['attId']);
|
|
$attachments['data'][$key]['zip'] = "$dir/attachments/" . $att['attId'];
|
|
if ($prefs['w_use_dir']) {
|
|
if (! $this->zip->addFile($prefs['w_use_dir'] . $att_info['path'], $attachments['data'][$key]['zip'])) {
|
|
$this->errors[] = 'Can not add the attachment';
|
|
$this->errorsArgs[] = $att_info['attId'];
|
|
return false;
|
|
}
|
|
} else {
|
|
if (! $this->zip->addFromString($attachments['data'][$key]['zip'], $att_info['data'])) {
|
|
$this->errors[] = 'Can not add the attachment';
|
|
$this->errorsArgs[] = $att_info['attId'];
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
$smarty->assign_by_ref('attachments', $attachments['data']);
|
|
}
|
|
}
|
|
|
|
|
|
// Deal with the history of the page.
|
|
|
|
if ($prefs['feature_history'] == 'y' && $this->config['history']) {
|
|
$histlib = TikiLib::lib('hist');
|
|
$history = $histlib->get_page_history($page, false);
|
|
foreach ($history as $key => $hist) {
|
|
$all = $histlib->get_version($page, $hist['version']); // can be optimised if returned in the list
|
|
//$history[$key]['data'] = $all['data'];
|
|
$history[$key]['zip'] = "$dir/history/" . $all['version'] . '.txt';
|
|
if (! $this->zip->addFromString($history[$key]['zip'], $all['data'])) {
|
|
$this->errors[] = 'Can not add the history';
|
|
$this->errorsArgs[] = $all['version'];
|
|
return false;
|
|
}
|
|
}
|
|
$smarty->assign_by_ref('history', $history);
|
|
}
|
|
|
|
|
|
// Render the metadata of the page with Smarty, and append it to the wiki.xml file, which is
|
|
// kept in the $xml member variable.
|
|
|
|
$smarty->assign_by_ref('config', $this->config);
|
|
$this->xml .= $smarty->fetch('tiki-export_page_xml.tpl');
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
/* import pages or structure */
|
|
public function import_pages($zipFile = 'dump/xml.zip', $config = null)
|
|
{
|
|
if (! empty($config)) {
|
|
$this->config = array_merge($this->config, $config);
|
|
}
|
|
|
|
// Open the Zip file
|
|
|
|
if (! ($this->zip = new ZipArchive())) {
|
|
$this->errors[] = 'Problem zip initialisation';
|
|
$this->errorsArgs[] = '';
|
|
return false;
|
|
}
|
|
|
|
if (! $this->zip->open($zipFile)) {
|
|
$this->errors[] = 'The file cannot be opened';
|
|
$this->errorsArgs[] = $zipFile;
|
|
return false;
|
|
}
|
|
|
|
|
|
// Open the wiki.xml
|
|
|
|
if (($this->xml = $this->zip->getFromName(WIKI_XML)) === false) {
|
|
$this->errors[] = 'Can not unzip';
|
|
$this->errorsArgs[] = WIKI_XML;
|
|
return false;
|
|
}
|
|
|
|
|
|
// Parse the wiki.xml
|
|
|
|
$parser = new page_Parser();
|
|
$parser->setInput($this->xml);
|
|
$ok = $parser->parse();
|
|
if (PEAR::isError($ok)) {
|
|
$this->errors[] = $ok->getMessage();
|
|
$this->errorsArgs[] = '';
|
|
return false;
|
|
}
|
|
$infos = $parser->getPages();
|
|
|
|
if ($this->config['debug']) {
|
|
echo 'XML PARSING<pre>';
|
|
print_r($infos);
|
|
echo '</pre>';
|
|
}
|
|
|
|
|
|
// Create the pages from the Zip file contents and the wiki.xml parse result.
|
|
|
|
foreach ($infos as $info) {
|
|
if (! $this->create_page($info)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
$this->zip->close();
|
|
return true;
|
|
}
|
|
|
|
|
|
// Create or update a page from within the Zip file and an xml parsing result
|
|
|
|
public function create_page($info)
|
|
{
|
|
global $prefs, $tiki_p_wiki_attach_files, $tiki_p_edit_comments, $tikidomain;
|
|
$tikilib = TikiLib::lib('tiki');
|
|
|
|
|
|
// Get the page content from the Zip file.
|
|
|
|
if (($info['data'] = $this->zip->getFromName($info['zip'])) === false) {
|
|
$this->errors[] = 'Can not unzip';
|
|
$this->errorsArgs[] = $info['zip'];
|
|
return false;
|
|
}
|
|
|
|
|
|
// Create or update the page.
|
|
|
|
if ($this->page_exists($info['name'])) {
|
|
|
|
// Page already exists. Update it with the page from the Zip file.
|
|
$old = true;
|
|
$tikilib->update_page(
|
|
$info['name'],
|
|
$info['data'],
|
|
'Updated from import',
|
|
! empty($this->config['fromUser']) ? $this->config['fromUser'] : $info['user'],
|
|
! empty($this->config['fromSite']) ? $this->config['fromSite'] : $info['ip'],
|
|
$info['description'],
|
|
0,
|
|
isset($info['lang']) ? $info['lang'] : '',
|
|
isset($info['is_html']) ? $info['is_html'] : false,
|
|
null,
|
|
null,
|
|
isset($info['wysiwyg']) ? $info['wysiwyg'] : null
|
|
);
|
|
} else {
|
|
|
|
// Page doesn't exists yet. Create it.
|
|
$old = false;
|
|
$tikilib->create_page(
|
|
$info['name'],
|
|
$info['hits'],
|
|
$info['data'],
|
|
$info['lastModif'],
|
|
$info['comment'],
|
|
! empty($this->config['fromUser']) ? $this->config['fromUser'] : $info['user'],
|
|
! empty($this->config['fromSite']) ? $this->config['fromSite'] : $info['ip'],
|
|
$info['description'],
|
|
isset($info['lang']) ? $info['lang'] : '',
|
|
isset($info['is_html']) ? $info['is_html'] : false,
|
|
null,
|
|
isset($info['wysiwyg']) ? $info['wysiwyg'] : null,
|
|
'',
|
|
0,
|
|
$info['created']
|
|
);
|
|
}
|
|
|
|
|
|
// Add the wiki page comments to the new or updated page.
|
|
|
|
if ($prefs['feature_wiki_comments'] == 'y' && $tiki_p_edit_comments == 'y' && ! empty($info['comments'])) {
|
|
$newThreadIds = [];
|
|
|
|
foreach ($info['comments'] as $comment) {
|
|
$commentslib = TikiLib::lib('comments');
|
|
$parentId = empty($comment['parentId']) ? 0 : $newThreadIds[$comment['parentId']];
|
|
if ($parentId) {
|
|
$reply_info = $commentslib->get_comment($parentId);
|
|
$in_reply_to = $reply_info['message_id'];
|
|
}
|
|
|
|
$newThreadIds[$comment['threadId']] = $commentslib->post_new_comment(
|
|
'wiki page:' . $info['name'],
|
|
$parentId,
|
|
$this->config['fromUser'] ? $this->config['fromUser'] : $comment['user'],
|
|
$comment['title'],
|
|
$comment['data'],
|
|
$message_id,
|
|
$in_reply_to,
|
|
'n',
|
|
'',
|
|
'',
|
|
'',
|
|
'',
|
|
$comment['date']
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
// Add the attachments to the new or updated page.
|
|
|
|
if ($prefs['feature_wiki_attachments'] == 'y'
|
|
&& $tiki_p_wiki_attach_files == 'y'
|
|
&& ! empty($info['attachments']))
|
|
{
|
|
// Interate over the attachments of the page
|
|
foreach ($info['attachments'] as $attachment) {
|
|
|
|
// Unzip the attachment, save its data in $attachment['data'].
|
|
if (($attachment['data'] = $this->zip->getFromName($attachment['zip'])) === false) {
|
|
$this->errors[] = 'Can not unzip attachment';
|
|
$this->errorsArgs[] = $attachment['zip'];
|
|
return false;
|
|
}
|
|
|
|
// $fhash: A unique name for the attached file, iff stored in directory (and not in
|
|
// database). This begins with a (MD5-) hash of the attachment file name.
|
|
if ($prefs['w_use_db'] == 'y') {
|
|
$fhash = '';
|
|
} else {
|
|
$fhash = $this->get_attach_hash_file_name($attachment['filename']);
|
|
|
|
// Write the attachment to the attachments directory, with the unique file name.
|
|
if ($fw = fopen($prefs['w_use_dir'] . $fhash, 'wb')) {
|
|
if (! fwrite($fw, $attachment['data'])) {
|
|
$this->errors[] = 'Cannot write to this file';
|
|
$this->errorsArgs[] = $prefs['w_use_dir'] . $fhash;
|
|
}
|
|
fclose($fw);
|
|
$attachment['data'] = '';
|
|
} else {
|
|
$this->errors[] = 'Cannot open this file';
|
|
$this->errorsArgs[] = $prefs['w_use_dir'] . $fhash;
|
|
}
|
|
}
|
|
|
|
// Register the attachment in the database.
|
|
$wikilib = TikiLib::lib('wiki');
|
|
$wikilib->wiki_attach_file(
|
|
$info['name'],
|
|
$attachment['filename'],
|
|
$attachment['filetype'],
|
|
$attachment['filesize'],
|
|
$attachment['data'], // The data of the attachment, iff it is stored in the database
|
|
$attachment['comment'],
|
|
$attachment['user'],
|
|
$fhash,
|
|
$attachment['created']
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
// ??? Add some of the images from the Zip file. This only does so for images in the
|
|
// img/wiki_up directory. Images in file galleries are silently ignored.
|
|
|
|
if ($prefs['feature_wiki_pictures'] == 'y' && ! empty($info['images'])) {
|
|
foreach ($info['images'] as $image) {
|
|
if (empty($image['zip'])) {//external link to image
|
|
continue;
|
|
}
|
|
if (($image['data'] = $this->zip->getFromName($image['zip'])) === false) {
|
|
$this->errors[] = 'Can not unzip image';
|
|
$this->errorsArgs[] = $image['zip'];
|
|
return false;
|
|
}
|
|
if ($image['where'] == 'wiki') {
|
|
$wiki_up = 'img/wiki_up/';
|
|
if ($tikidomain) {
|
|
$wiki_up .= "$tikidomain/";
|
|
}
|
|
$name = str_replace('img/wiki_up/', '', $image['wiki']);
|
|
file_put_contents($wiki_up . $name, $image['data']);
|
|
chmod($wiki_up . $name, 0644);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Add the page history to the new or updated page.
|
|
|
|
if ($prefs['feature_history'] == 'y' && ! empty($info['history'])) {
|
|
$query = 'select max(`version`) from `tiki_history` where `pageName`=?';
|
|
$maxVersion = $this->getOne($query, [$info['name']]);
|
|
|
|
if (! $maxVersion) {
|
|
$maxVersion = 0;
|
|
}
|
|
$newVersion = $maxVersion;
|
|
|
|
foreach ($info['history'] as $version) {
|
|
if (($version['data'] = $this->zip->getFromName($version['zip'])) === false) {
|
|
$this->errors[] = 'Can not unzip history';
|
|
$this->errorsArgs[] = $version['version'];
|
|
return false;
|
|
}
|
|
$query = 'insert into `tiki_history`(`pageName`, `version`, `lastModif`, `user`, `ip`, `comment`, `data`, `description`) values(?,?,?,?,?,?,?,?)';
|
|
|
|
$this->query(
|
|
$query,
|
|
[
|
|
$info['name'],
|
|
$version['version'] + $maxVersion,
|
|
$old ? $tikilib->now : $version['lastModif'],
|
|
$version['user'],
|
|
$version['ip'],
|
|
$version['comment'],
|
|
$version['data'],
|
|
$version['description']
|
|
]
|
|
);
|
|
|
|
$newVersion = max($version['version'] + $maxVersion, $newVersion);
|
|
}
|
|
$query = 'update `tiki_pages` set `version`=? where `pageName`=?';
|
|
$this->query($query, [$newVersion, $info['name']]);
|
|
}
|
|
|
|
|
|
// Import a structure.
|
|
|
|
if ($prefs['feature_wiki_structure'] == 'y' && ! empty($info['structure'])) {
|
|
$structlib = TikiLib::lib('struct');
|
|
//TODO alias
|
|
if ($info['structure'] == 1) {
|
|
$this->structureStack[$info['structure']] = $structlib->s_create_page(null, null, $info['name'], '');
|
|
if (empty($this->structureStack[$info['structure']])) {
|
|
$this->errors[] = 'A structure already exists';
|
|
$this->errorsArgs[] = $info['name'];
|
|
return false;
|
|
}
|
|
} elseif (! empty($info['structure'])) {
|
|
$this->structureStack[$info['structure']] = $structlib->s_create_page(
|
|
$this->structureStack[$info['structure'] - 1],
|
|
isset($this->structureStack[$info['structure']]) ? $this->structureStack[$info['structure']] : '',
|
|
$info['name'],
|
|
'',
|
|
$this->structureStack[1]
|
|
);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
|
|
} // create_page()
|
|
|
|
} // class XmlLib
|
|
|
|
|
|
$xmllib = new XmlLib();
|
|
|
|
|
|
class page_Parser extends XML_Parser
|
|
{
|
|
public $page;
|
|
public $currentTag = null;
|
|
public $context = null;
|
|
public $folding = false; // keep tag as original
|
|
public $commentsStack = [];
|
|
public $commentId = 0;
|
|
public $iStructure = 0;
|
|
|
|
public function startHandler($parser, $name, $attribs)
|
|
{
|
|
switch ($name) {
|
|
case 'page':
|
|
$this->context = null;
|
|
if (is_array($attribs)) {
|
|
$this->page = [
|
|
'data' => '',
|
|
'comment' => '',
|
|
'description' => '',
|
|
'user' => 'admin',
|
|
'ip' => '0.0.0.0',
|
|
'lang' => '',
|
|
'is_html' => false,
|
|
'hash' => null,
|
|
'wysiwyg' => null
|
|
];
|
|
$this->page = array_merge($this->page, $attribs);
|
|
}
|
|
if ($this->iStructure > 0) {
|
|
$this->page['structure'] = $this->iStructure;
|
|
}
|
|
break;
|
|
|
|
case 'structure':
|
|
++$this->iStructure;
|
|
break;
|
|
|
|
case 'comments':
|
|
$comentsStack = [];
|
|
break;
|
|
case 'attachments':
|
|
case 'history':
|
|
case 'images':
|
|
$this->context = $name;
|
|
$this->i = -1;
|
|
break;
|
|
|
|
case 'comment':
|
|
if ($this->context == 'comments') {
|
|
++$this->i;
|
|
$this->page[$this->context][$this->i] = $attribs;
|
|
$this->page[$this->context][$this->i]['parentId'] = empty($this->commentsStack) ? 0 : $this->commentsStack[count($this->commentsStack) - 1];
|
|
$this->page[$this->context][$this->i]['threadId'] = ++$this->commentId;
|
|
array_push($this->commentsStack, $this->commentId);
|
|
} else {
|
|
$this->currentTag = $name;
|
|
}
|
|
break;
|
|
|
|
case 'attachment':
|
|
++$this->i;
|
|
$this->page[$this->context][$this->i] = ['comment' => ''];
|
|
$this->page[$this->context][$this->i] = array_merge($this->page[$this->context][$this->i], $attribs);
|
|
break;
|
|
|
|
case 'version':
|
|
++$this->i;
|
|
$this->page[$this->context][$this->i] = ['comment' => '', 'description' => '', 'ip' => '0.0.0.0'];
|
|
$this->page[$this->context][$this->i] = array_merge($this->page[$this->context][$this->i], $attribs);
|
|
break;
|
|
|
|
case 'image':
|
|
++$this->i;
|
|
$this->page[$this->context][$this->i] = $attribs;
|
|
break;
|
|
|
|
default:
|
|
$this->currentTag = $name;
|
|
break;
|
|
}
|
|
}
|
|
|
|
public function endHandler($parser, $name)
|
|
{
|
|
$this->currentTag = null;
|
|
switch ($name) {
|
|
case 'comments':
|
|
case 'attachments':
|
|
case 'history':
|
|
case 'images':
|
|
$this->context = null;
|
|
break;
|
|
|
|
case 'comment':
|
|
array_pop($this->commentsStack);
|
|
break;
|
|
|
|
case 'page':
|
|
$this->pages[] = $this->page;
|
|
break;
|
|
|
|
case 'structure':
|
|
--$this->iStructure;
|
|
break;
|
|
}
|
|
}
|
|
|
|
public function cdataHandler($parser, $data)
|
|
{
|
|
$data = trim($data);
|
|
if (empty($data)) {
|
|
return true;
|
|
}
|
|
if (empty($this->context)) {
|
|
$this->page[$this->currentTag] = $data;
|
|
} else {
|
|
$this->page[$this->context][$this->i][$this->currentTag] = $data;
|
|
}
|
|
}
|
|
|
|
public function getPages()
|
|
{
|
|
return $this->pages;
|
|
}
|
|
}
|