Difference between revisions of "Xmlwiki.php"
From Organic Design wiki
| Line 13: | Line 13: | ||
# - only change rendering, not editing | # - only change rendering, not editing | ||
# - rendering an xwArticle, | # - rendering an xwArticle, | ||
| − | # - compiles php-transform-articles,CSS's & XSLT's from env+ | + | # - compiles php-transform-articles,CSS's & XSLT's from env+doc (the result of each becomes the source of the next) |
# - execute php-transform-articles & XSLT's in order (CSS's are left to the end) | # - execute php-transform-articles & XSLT's in order (CSS's are left to the end) | ||
# - returns html-description with a CSS containing includes to CSS list | # - returns html-description with a CSS containing includes to CSS list | ||
| Line 19: | Line 19: | ||
# - layouts would come with a separate collection of CSS's | # - layouts would come with a separate collection of CSS's | ||
# - CSS's need to themselves be collections of colours, headings etc | # - CSS's need to themselves be collections of colours, headings etc | ||
| − | + | ||
| − | |||
# LATER: | # LATER: | ||
# use XInclude to build large docs from others | # use XInclude to build large docs from others | ||
| − | # use docBook | + | # use docBook or DSSSL |
# <? is a processing instruction | # <? is a processing instruction | ||
# eg. <?xml-stylesheet href="person.css" type="text/css"?> or <?php... | # eg. <?xml-stylesheet href="person.css" type="text/css"?> or <?php... | ||
| Line 31: | Line 30: | ||
# INIT | # INIT | ||
| + | # - do admin and exit if running directly | ||
# - get wiki/request env | # - get wiki/request env | ||
# - get article | # - get article | ||
# - permissions | # - permissions | ||
| + | # - build env (if action=raw, env is empty but a header is added) | ||
# INPUT | # INPUT | ||
# - validate xml and report error or, | # - validate xml and report error or, | ||
| Line 40: | Line 41: | ||
# - trap MediaWiki output | # - trap MediaWiki output | ||
# - extract content and links | # - extract content and links | ||
| − | # - if view/preview, do | + | # - if view/preview/raw, do transform: |
# - if docType is an xwArticle, see above | # - if docType is an xwArticle, see above | ||
# - replace view/preview with transformed article | # - replace view/preview with transformed article | ||
| Line 80: | Line 81: | ||
# Get groups this user belongs to from users' special-article | # Get groups this user belongs to from users' special-article | ||
$xwUserGroups[] = $xwUserName; // This allows users to be specified in permissions-lists in addition to groups | $xwUserGroups[] = $xwUserName; // This allows users to be specified in permissions-lists in addition to groups | ||
| + | |||
| + | # Build transform environment (later from prefs, site etc) | ||
| + | if ($action == 'raw') { | ||
| + | # Raw article is requested, so env is empty | ||
| + | $xwEnv = array(); | ||
| + | # TODO: work out what kind of content it is (only if its an xwArticle can this work) | ||
| + | # header("Content-type: application/pdf"); | ||
| + | # header("Content-Disposition: attachment; filename=downloaded.pdf"); | ||
| + | } | ||
| + | else { | ||
| + | # Create default environment (the name of another article) | ||
| + | $xwEnv = array('defaultTemplate.php'); | ||
| + | } | ||
| + | |||
} | } | ||
Revision as of 09:33, 30 May 2005
<?php
# xmlWiki - MediaWiki XML Hack
# Nad - 2005-05-18
#
# Output Hook: Transforms output generated by MediaWiki and
#
# - Adds basic content-management, permissions and publishing to the MediaWiki
# - All articles are XML
# - Impliment by calling this script directly in browser
# FOR NOW:
# - only change rendering, not editing
# - rendering an xwArticle,
# - compiles php-transform-articles,CSS's & XSLT's from env+doc (the result of each becomes the source of the next)
# - execute php-transform-articles & XSLT's in order (CSS's are left to the end)
# - returns html-description with a CSS containing includes to CSS list
# - PAGE LAYOUT is just a php-transform-article which SURROUNDS the current DOM with raw layout
# - layouts would come with a separate collection of CSS's
# - CSS's need to themselves be collections of colours, headings etc
# LATER:
# use XInclude to build large docs from others
# use docBook or DSSSL
# <? is a processing instruction
# eg. <?xml-stylesheet href="person.css" type="text/css"?> or <?php...
# ---------------------------------------------------------------------------------------------------------------------- #
# INIT
# - do admin and exit if running directly
# - get wiki/request env
# - get article
# - permissions
# - build env (if action=raw, env is empty but a header is added)
# INPUT
# - validate xml and report error or,
# - process form-input (backslashes etc if necessary)
# OUTPUT
# - trap MediaWiki output
# - extract content and links
# - if view/preview/raw, do transform:
# - if docType is an xwArticle, see above
# - replace view/preview with transformed article
# - render output
# - if saving, foreach in publish-list,
# - do transform but with specified env
# - publish
# FUNCTION
# - get article as dom
# - process dom-article (pass PT,XSLT list and DOM-article, returns DOM-result)
# - etxract hrefs from text
# - message
# ADMIN
# - enable/disable patch
# ---------------------------------------------------------------------------------------------------------------------- #
# INIT
# If xmlwiki.php requested directly, return admin page
if (eregi("xmlwiki\\.php", $_SERVER['SCRIPT_NAME'])) xwAdminPage();
else {
# Otherwise set up xmlWiki global environment ready for input and output processing
$xwArticleCache = array();
$xwEditingArticle = isset($_REQUEST['action'])&&($_REQUEST['action'] == 'edit');
$xwEditingXML = isset($_REQUEST['action'])&&($_REQUEST['action'] == 'xwXML');
$xwViewingArticle = null; # preview too
$xwSavingArticle = isset($_REQUEST['wpSave']);
$xwSpecialArticle = null; # do not treat content as xml
$xwArticleTitle = $wgTitle->mTextform;
$xwArticleDOM = xwGetArticle($xwArticleTitle); # DOM object of wiki article
$xwUserName = $wgUser->mName;
$xwUserDOM = xwGetArticle("User:$xwUserName");
$xwUserGroups = null; # Groups this user belongs to (incl. self)
# Get perms for this article
$xwReadable = null; # True if this article is readable by this user
$xwWritable = null; # True if this article is writeable by this user
# Get groups this user belongs to from users' special-article
$xwUserGroups[] = $xwUserName; // This allows users to be specified in permissions-lists in addition to groups
# Build transform environment (later from prefs, site etc)
if ($action == 'raw') {
# Raw article is requested, so env is empty
$xwEnv = array();
# TODO: work out what kind of content it is (only if its an xwArticle can this work)
# header("Content-type: application/pdf");
# header("Content-Disposition: attachment; filename=downloaded.pdf");
}
else {
# Create default environment (the name of another article)
$xwEnv = array('defaultTemplate.php');
}
}
# ---------------------------------------------------------------------------------------------------------------------- #
# INPUT
# Parse and process input from forms
# - the form can just post changes for xml
function xwProcessInput() {
global $xwEditingArticle;
global $xwSavingArticle;
global $xwReadable;
global $xwWritable;
global $xwArticleDOM;
# If article is being updated,
if ($xwSavingArticle) {
global $_POST;
# If valid xml posted, replace articleDOM
if ($inputDOM = @domxml_open_mem($_POST["xw.xml"])) $articleDOM = $inputDOM;
# later: parse POST updating articleDOM
foreach (preg_grep("/^xw\\.(.+)$/", array_keys($_POST)) as $key) {
$inputPath = split('.', $key);
}
# If description posted, update
if (isset($_POST["wpTextbox1"])) {
# write new description to articleDOM
}
# Convert articleDOM to text and put into POST data for MediaWiki to process
$_POST["wpTextbox1"] = $articleDOM->dump_mem(false);
}
}
# ---------------------------------------------------------------------------------------------------------------------- #
# OUTPUT
# Generate new output to send back to browser
function xwProcessOutput() {
global $wgOut;
global $xwEditingArticle;
global $xwEditingXML;
global $xwViewingArticle;
global $xwSavingArticle;
global $xwSpecialArticle;
global $xwArticleTitle;
global $xwArticleDOM;
global $xwUserName;
global $xwUserDOM;
global $xwUserGroups;
global $xwReadable;
global $xwWritable;
$xwTransformedArticle = null;
$xwPublishList = array();
$xwOutput = '';
# First trap Wiki output and extract content and links (should use $ver like Admin Page)
ob_start();
$wgOut->output();
$xwWikiOutput = ob_get_clean();
$xwWikiContent = preg_match('/\<!-- start content -->(.+)<!-- end content -->/sm', $xwWikiOutput, $xwMatch)
? $xwMatch[1] : '';
$xwUserLinks = preg_match('/id="p-personal"(.+?)<\/div>/s', $xwWikiOutput, $xwMatch)
? xwExtractHrefs($xwMatch[1]) : array();
$xwArticleLinks = preg_match('/id="p-cactions"(.+?)<\/div>/s', $xwWikiOutput, $xwMatch)
? xwExtractHrefs($xwMatch[1]) : array();
$xwArticleLinks[] = "<a href=\"./index.php?title=$xwArticleTitle&action=xwXML\">xml</a>";
# Test output
?><center><table border cellpadding=0 cellspacing=0><?
print '<tr><td>'.join(' | ', $xwUserLinks);
print '<tr><td>'.join(' | ', $xwArticleLinks);
print '<tr><td>'.htmlentities($xwArticleDOM->dump_mem(true));
print '<tr><td>'.$xwWikiContent;
?></table></center><?
# Transform
# - This env still needs to apply an outer layout etc
# - The local-env and the DTD determines transforming/rendering
# - if DTD says its just text (or special page) render normal
# - The DTD's need to work outside wiki, so we need to be able to specifiy lang in request
# eg. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
# <!DOCTYPE greeting SYSTEM "hello.dtd">
# - article/input-description/input-xml/input-tree-operation
# NOTE: we need to handle edit/discuss/history/login/prefs...
if ($xwEditingXML) {
# Editing XML, render textarea (later tree)
$xwOutput .= '\n<textarea name="xw.xml">'.$xwArticleDOM->dump_mem(true).'</textarea>\n';
}
if ($xwEditingArticle || $xwSpecialArticle) {
# If not viewing output wiki content
$xwOutput .= $wikiContent;
}
if ($xwViewingArticle) {
# render article in current context (transform article)
# - html, ....
# Apply stylesheets
$xwTransformedArticle = null;
# Replace output-buffer content with processed article
$xwOutput .= $xwTransformedArticle;
}
# Publish the article if it has just been updated
if ($xwSavingArticle) {
foreach ($xwPublishList as $xwDestination) {
if ($xwHandle = fopen($xwDestination, 'a')) {
fwrite($xwHandle, $xwTransformedArticle);
fclose($xwHandle);
$xwOutput .= xwMessage("Article published to $cmDestination", 'green');
} else $xwOutput .= xwMessage("Failed to publish to $cmDestination", 'red');
}
}
# Render output-buffer through page template
print $xwOutput;
}
# ---------------------------------------------------------------------------------------------------------------------- #
# FUNCTIONS
# Retreive XML wiki-article and return as a DOM object
# - DOM articles are cached in $xwArticleCache for reuse in recursive processing
function xwGetArticle($articleTitle) {
# Return with results if already cached
global $xwArticleCache;
if (isset($xwArticleCache[$articleTitle])) return $xwArticleCache[$articleTitle];
# Get wiki article content (XML)
$articleXML = new Article(Title::newFromText($articleTitle));
$articleXML = $articleXML->getContent(false);
# Convert to DOM object
if (!$articleDOM = @domxml_open_mem($articleXML)) $articleDOM = domxml_new_doc("1.0");
return $xwArticleCache[$articleTitle] = $articleDOM;
}
# Return a list of the hrefs found in the passed content
function xwExtractHrefs($content) {
preg_match_all('/(<a.+?<\/a>)/', $content, $match);
return $match[1];
}
# Render a xmlWiki system message
function xwMessage($msg, $col) {
return "\n<table width=100% border=0><tr><td align=center>
<table width=50% border bordercolor=#bbbbbb borderwidth=1 bgcolor=#999999><tr><td align=center>
<font face=arial size=2 color=$col><b>$msg</b></font>
</table></table>\n";
}
# ---------------------------------------------------------------------------------------------------------------------- #
# ADMIN
function xwAdminPage() {
?><html><head><title>xmlWiki Admin Page</title></head><body bgcolor=#cccccc>
<table border=0 width=100% cellpadding=0 cellspacing=0>
<tr><td align=center><table border=0 width=30%>
<tr><td align=center>
<a href="./index.php/xmlWiki"><img src="./xmlwiki.jpg" border=0 alt="xmlWiki"></a>
<tr><td align=center bgcolor=#003366>
<b><font size=5 color=white face=helvetica>xmlWiki Admin Page</font></b>
</table></table><br><br><br><br><?
# back up index.php if doesn't already exist
if (!file_exists('./index.bak')) {
if (!copy('./index.bak', './index.php')) {
print xwMessage('Could not back up index.php!', '#d00000');
exit;
}
}
if (array_key_exists('enable', $_GET)) {
# Replace from backup before enabling
if (!copy('./index.bak', './index.php'))
print xwMessage('Could not copy index.bak over index.php', '#d00000');
require_once('./Version.php');
$ver = $wgSoftwareRevision;
# Matches for patch-points/MediaWiki versions
$requireMatch['1002'] = "/^wfProfileOut\\( *'main-misc-setup' *\\);$/m";
$inputMatch['1002'] = "/^wfProfileIn\\( *'main-action' *\\);$/m";
$outputMatch['1002'] = "/\\\$wgOut->output\\(\\);/m";
# Apply patches
if (preg_match($requireMatch[$ver], $file = join('', file('./index.php')))
&& preg_match($inputMatch[$ver], $file)
&& preg_match($outputMatch[$ver], $file)) {
$file = preg_replace($requireMatch[$ver], "wfProfileOut( 'main-misc-setup' );\nrequire_once( './xmlwiki.php' );", $file);
$file = preg_replace($inputMatch[$ver], "xwProcessInput();\nwfProfileIn( 'main-action' );", $file);
$file = preg_replace($outputMatch[$ver], "xwProcessOutput();", $file);
if ($handle = fopen('./index.php', 'w')) {
fwrite($handle, $file);
fclose($handle);
} else print xwMessage('Could not open index.php for writing!', '#d00000');
} else print xwMessage('Could not match content of index.php script!', '#d00000');
}
elseif (array_key_exists('disable', $_GET)) {
# Replace from backup
if (!copy('./index.bak', './index.php'))
print xwMessage('Could not copy index.bak over index.php', '#d00000');
}
# Print current state
if (filesize('./index.php') == filesize('./index.bak'))
print xwMessage('xmlWiki is currently disabled. [ <a href="./xmlwiki.php?enable">enable</a> ]', '#003366');
else print xwMessage('xmlWiki is currently enabled. [ <a href="./xmlwiki.php?disable">disable</a> ]', '#003366');
?><br><br><br><table border=0 width=100% cellpadding=0 cellspacing=0>
<tr><td align=center colspan=3><table border=0 width=50%>
<td align=right valign=top><a href="http://w3c.org/"><img src="./xhtml.jpg" alt="XHTML1.0" border=0 /></a>
<td align=right valign=top><a href="http://www.php.net/"><img src="./php.jpg" alt="PHP" border=0 /></a>
<td align=right valign=top><a href="http://www.mediawiki.org/"><img src="./mediawiki.jpg" alt="MediaWiki" border=0 /></a>
</table></table><br><br></body></html><?
}
?>



