Difference between revisions of "Xmlwiki.php"

From Organic Design wiki
Line 3: Line 3:
 
# xmlWiki - MediaWiki XML Hack
 
# xmlWiki - MediaWiki XML Hack
 
# Nad - 2005-05-18
 
# 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:
+
# CSS STYLES
# - only change rendering, not editing
+
# the are accessed via http, so their article url can be referred to locally in the html
# - rendering an xwArticle,
+
# - maybe make the default request 'raw' and must specifically request 'view'
#   - 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:
 
# LATER:
# use XInclude to build large docs from others
+
# allow XIncludes to build large docs from others
# use docBook or DSSSL
+
# allow docBook and DSSSL content
# <? is a processing instruction
 
# eg. <?xml-stylesheet href="person.css" type="text/css"?>  or  <?php...
 
  
 
# ---------------------------------------------------------------------------------------------------------------------- #
 
# ---------------------------------------------------------------------------------------------------------------------- #
 +
# SCRIPT CONTENTS
  
 
# INIT
 
# INIT
Line 41: Line 28:
 
# - extract content and links
 
# - extract content and links
 
# - if view/preview/raw, do transform:
 
# - if view/preview/raw, do transform:
#  - if docType is an xwArticle, see above
 
 
#  - replace view/preview with transformed article
 
#  - replace view/preview with transformed article
 
# - render output
 
# - render output
Line 47: Line 33:
 
#  - do transform but with specified env
 
#  - do transform but with specified env
 
#  - publish
 
#  - publish
# FUNCTION
+
# TRANSFORM
# - get article as dom
 
 
# - process dom-article (pass PT,XSLT list and DOM-article, returns DOM-result)
 
# - process dom-article (pass PT,XSLT list and DOM-article, returns DOM-result)
 +
# - if docType is an xwArticle, see above
 +
# TRANSFORMS
 +
# - document transforms
 +
# - image transforms
 +
# - layout transforms
 +
# - database table transforms
 +
# FUNCTIONS
 +
# - get article
 
# - etxract hrefs from text
 
# - etxract hrefs from text
# - message
+
# - message/log
 
# ADMIN
 
# ADMIN
 
# - enable/disable patch
 
# - enable/disable patch
Line 63: Line 56:
  
 
# Otherwise set up xmlWiki global environment ready for input and output processing
 
# 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;
 
$xwArticleTitle = $wgTitle->mTextform;
$xwArticleDOM = xwGetArticle($xwArticleTitle); # DOM object of wiki article
+
$xwArticle = xwGetArticle($xwArticleTitle);
 +
$xwDocType = null;
 +
$xwRoot = null;
 +
 
 +
$xwEdit = isset($_REQUEST['action'])&&($_REQUEST['action'] == 'edit');
 +
$xwView = isset($_REQUEST['action'])&&($_REQUEST['action'] == 'view');
 +
$xwRaw = isset($_REQUEST['action'])&&($_REQUEST['action'] == 'raw');
 +
$xwPreview = isset($_REQUEST['wpPreview']);
 +
$xwSave = isset($_REQUEST['wpSave']);
 +
 
 
$xwUserName = $wgUser->mName;
 
$xwUserName = $wgUser->mName;
$xwUserDOM = xwGetArticle("User:$xwUserName");
+
$xwUserArticle = xwGetArticle("User:$xwUserName");
$xwUserGroups = null; # Groups this user belongs to (incl. self)
+
$xwReadable = true;
 +
$xwWritable = true;
 +
 
 +
$xwMessages = array();
 +
$xwArticleCache = array();
 +
$xwEnv = array();
  
# Get perms for this article
+
# If article is an object,
$xwReadable = null; # True if this article is readable by this user
+
if (is_object($xwArticle)) {
$xwWritable = null; # True if this article is writeable by this user
+
# Get doc info
# Get groups this user belongs to from users' special-article
+
$xwDocType = $xwArticle->doctype->name;
$xwUserGroups[] = $xwUserName; // This allows users to be specified in permissions-lists in addition to groups
+
$xwRoot = $xwArticle->document_element();  
 +
# Get perms
 +
$xwUserGroups[] = $xwUserName; // This allows users to be specified in permissions-lists in addition to groups
 +
$xwReadable = null; # True if this article is readable by this user
 +
$xwWritable = null; # True if this article is writeable by this user
 +
}
  
# Build transform environment (later from prefs, site etc)
+
# Build default transform environment (later from prefs, site etc)
if ($action == 'raw') {
+
if ($xwRaw) {
 
# Raw article is requested, so env is empty
 
# 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 {
 
else {
 
# Create default environment (the name of another article)
 
# Create default environment (the name of another article)
$xwEnv = array('defaultTemplate.php');
+
# - this does default transforms depending on type (eg highlighting for *.php)
 +
$xwEnv[] = '';
 
}
 
}
 
 
Line 98: Line 101:
 
# ---------------------------------------------------------------------------------------------------------------------- #
 
# ---------------------------------------------------------------------------------------------------------------------- #
 
# INPUT
 
# INPUT
 +
 +
# No input processing for now
  
 
# Parse and process input from forms
 
# Parse and process input from forms
# - the form can just post changes for xml
 
 
function xwProcessInput() {
 
function xwProcessInput() {
  
global $xwEditingArticle;
+
global $xwArticle;
global $xwSavingArticle;
+
global $xwArticleTitle;
 +
global $xwRoot;
 +
global $xwDocType;
 +
 
 +
global $xwSave;
 +
 
 
global $xwReadable;
 
global $xwReadable;
 
global $xwWritable;
 
global $xwWritable;
global $xwArticleDOM;
 
  
 
# If article is being updated,
 
# If article is being updated,
if ($xwSavingArticle) {
+
if ($xwSave) {
 
global $_POST;
 
global $_POST;
# If valid xml posted, replace articleDOM
+
if (!$xwReadable || !$xwWritable) die("I'm sorry Dave, I'm afraid I can't do that.");
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);
 
 
}
 
}
  
Line 136: Line 133:
 
global $wgOut;
 
global $wgOut;
 
 
global $xwEditingArticle;
+
global $xwArticle;
global $xwEditingXML;
 
global $xwViewingArticle;
 
global $xwSavingArticle;
 
global $xwSpecialArticle;
 
 
global $xwArticleTitle;
 
global $xwArticleTitle;
global $xwArticleDOM;
+
global $xwRoot;
 +
global $xwDocType;
 +
 
 +
global $xwView;
 +
global $xwPreview;
 +
global $xwSave;
 +
 
 
global $xwUserName;
 
global $xwUserName;
global $xwUserDOM;
+
global $xwUserArticle;
global $xwUserGroups;
 
 
global $xwReadable;
 
global $xwReadable;
 
global $xwWritable;
 
global $xwWritable;
 
$xwTransformedArticle = null;
 
$xwPublishList = array();
 
$xwOutput = '';
 
  
 
# First trap Wiki output and extract content and links (should use $ver like Admin Page)
 
# First trap Wiki output and extract content and links (should use $ver like Admin Page)
Line 157: Line 151:
 
$wgOut->output();
 
$wgOut->output();
 
$xwWikiOutput = ob_get_clean();
 
$xwWikiOutput = ob_get_clean();
$xwWikiContent = preg_match('/\<!-- start content -->(.+)<!-- end content -->/sm', $xwWikiOutput, $xwMatch)
+
? $xwMatch[1] : '';
+
# Extract links (not used currently)
 
$xwUserLinks = preg_match('/id="p-personal"(.+?)<\/div>/s', $xwWikiOutput, $xwMatch)
 
$xwUserLinks = preg_match('/id="p-personal"(.+?)<\/div>/s', $xwWikiOutput, $xwMatch)
 
? xwExtractHrefs($xwMatch[1]) : array();
 
? xwExtractHrefs($xwMatch[1]) : array();
 
$xwArticleLinks = preg_match('/id="p-cactions"(.+?)<\/div>/s', $xwWikiOutput, $xwMatch)
 
$xwArticleLinks = preg_match('/id="p-cactions"(.+?)<\/div>/s', $xwWikiOutput, $xwMatch)
 
? xwExtractHrefs($xwMatch[1]) : array();
 
? xwExtractHrefs($xwMatch[1]) : array();
$xwArticleLinks[] = "<a href=\"./index.php?title=$xwArticleTitle&action=xwXML\">xml</a>";
 
  
# Test output
+
# Security
?><center><table border cellpadding=0 cellspacing=0><?
+
if (!$xwReadable) {
print '<tr><td>'.join(' | ', $xwUserLinks);
+
# change output to access denied message if !readable
print '<tr><td>'.join(' | ', $xwArticleLinks);
+
}
print '<tr><td>'.htmlentities($xwArticleDOM->dump_mem(true));
+
if (!$xwWritable) {
print '<tr><td>'.$xwWikiContent;
+
# remove edit link
?></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">
+
# Transform article for raw request (ignores wiki-output completely)
#    <!DOCTYPE greeting SYSTEM "hello.dtd">
+
if ($xwRaw) $xwOutput = xwTransformArticle();
 
# - 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) {
+
# Transform article for normal view
# If not viewing output wiki content
+
if ($xwView) {
$xwOutput .= $wikiContent;
+
if (preg_match('/^(.+<!-- start content -->).+(<!-- end content -->.+)$/m', $xwOutput, $xwMatch)) {
 +
$xwOutput = xwTransformArticle();
 +
$xwOutput = $xwMatch[1].$xwOutput.$xwMatch[2];
 +
} else xwMessage('xmlWiki couldn\'t match view-output!', 'red');
 
}
 
}
 
if ($xwViewingArticle) {
 
# render article in current context (transform article)
 
# - html, ....
 
  
# Apply stylesheets
+
# Transform article for preview
$xwTransformedArticle = null;
+
if ($xwPreview) {
+
if (preg_match('/^(.+<!-- start content -->.+Remember.+saved!.+?<\\/p>).+(<script.+?<\\/script>.?<form id="editform".+<!-- end content -->.+)$/m', $xwOutput, $xwMatch)) {
# Replace output-buffer content with processed article
+
$xwOutput = xwTransformArticle();
$xwOutput .= $xwTransformedArticle;
+
$xwOutput = $xwMatch[1].$xwOutput.$xwMatch[2];
 +
} else xwMessage('xmlWiki couldn\'t match preview-output!', 'red');
 
}
 
}
  
# Publish the article if it has just been updated
+
# Transform article for publishing
if ($xwSavingArticle) {
+
if ($xwSave && is_object($xwArticle)) {
 +
# Get publish list
 +
$xwPublishList = $xwRoot->get_elements_by_tagname('publish');
 +
if (count($xwPublishList)) $xwPublishList = $xwPublishList[0]->dump_mem(true);
 +
$xwPublishList = split(',', $xwPublishList);
 +
$xwOutput = xwTransformArticle();
 +
# Publish each item
 
foreach ($xwPublishList as $xwDestination) {
 
foreach ($xwPublishList as $xwDestination) {
 
if ($xwHandle = fopen($xwDestination, 'a')) {
 
if ($xwHandle = fopen($xwDestination, 'a')) {
 
fwrite($xwHandle, $xwTransformedArticle);
 
fwrite($xwHandle, $xwTransformedArticle);
 
fclose($xwHandle);
 
fclose($xwHandle);
$xwOutput .= xwMessage("Article published to $cmDestination", 'green');
+
xwMessage("Article published to $cmDestination", 'green');
} else $xwOutput .= xwMessage("Failed to publish to $cmDestination", 'red');
+
} else xwMessage("Failed to publish to $cmDestination", 'red');
 
}
 
}
 
}
 
}
  
# Render output-buffer through page template
+
# Render final output and messages
 +
# - not good if content isn't plain-text anymore!
 +
foreach ($xwMessages as $msg) $xwOutput .= $msg;
 
print $xwOutput;
 
print $xwOutput;
 +
}
 +
 +
# ---------------------------------------------------------------------------------------------------------------------- #
 +
# TRANSFORM
 +
 +
function xwTransformArticle() {
 +
 +
global $xwArticle;
 +
global $xwArticleTitle;
 +
global $xwDocType;
 +
 +
# If content is object,
 +
if (is_object($xwArticle)) {
 +
# we should check DTD's here for document, image, table, layout
 +
# 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">
 +
if ($xwDocType == 'xmlwiki') {
 +
# Get the documents transforms
 +
# - the first transforms adjust the document while its still a DOM object
 +
# - but at some point it would normally transform to text,
 +
# - it may then have some further text-based transforms
 +
$xwTransforms = $root->get_elements_by_tagname('transform');
 +
 +
#  - add php-transform-articles,CSS's & XSLT's to $xwEnv
 +
#  - $xwEnv transforms first!
 +
}
 +
 +
# If object wasn't one of ours, or didn't get transformed to a string...
 +
if (!is_string($xwArticle)) {
 +
# validate, report errors
 +
 +
# apply stylesheet/XSLT if xml asks for one,
 +
 +
# Convert DOM back to XML
 +
$xwArticle = $xwArticle->dump_mem(true);
 +
}
 +
}
 +
 +
# Apply syntax highlighting if string (even if article was an object, it will be a string now)
 +
# - This isn't a transform because it also applies to non-object articles
 +
if (is_string($xwArticle)) {
 +
# First check for entire article highlighting
 +
if (ereg('\\.as$', $xwArticleTitle)) $xwLang = 'actionscript';
 +
elseif (ereg('\\.py$', $xwArticleTitle)) $xwLang = 'python';
 +
elseif (ereg('\\.java$', $xwArticleTitle)) $xwLang = 'java';
 +
elseif (ereg('\\.(cpp)|(h)$', $xwArticleTitle)) $xwLang = 'cpp';
 +
elseif (ereg('\\.js$', $xwArticleTitle)) $xwLang = 'javascript';
 +
elseif (ereg('\\.css$', $xwArticleTitle)) $xwLang = 'css';
 +
elseif (ereg('^#![/a-zA-Z0-9]+\\/perl', $xwArticle)) $xwLang = 'perl';
 +
elseif (ereg('^#![/a-zA-Z0-9]+sh', $xwArticle)) $xwLang = 'bash';
 +
elseif (ereg('^<?xml', $xwArticle)) $xwLang = 'xml';
 +
elseif (ereg('^<?html', $xwArticle)) $xwLang = 'html4strict';
 +
else {
 +
# Otherwise, parse article for internal highlights
 +
# <?,<% lang (default % is asp, default ? is php)
 +
# <script language= (default is javascript)
 +
 +
$xwLang = false;
 +
}
 +
 +
# Highlight entire article if xwLang has been set
 +
if ($xwLang)
 +
$xwGeshi = new GeSHi($xwArticle, $xwLang, "extensions/geshi/geshi");
 +
$geshi->set_keywords_style(1, 'font-weight: 100;', true);
 +
$geshi->set_comments_style
 +
$geshi->set_escape_char_style
 +
$geshi->set_brackets_style
 +
$geshi->set_strings_style
 +
$geshi->set_numbers_style
 +
$geshi->set_methods_style
 +
$geshi->set_symbols_style
 +
$geshi->set_regexps_style
 +
$geshi->set_script_style
 +
$xwArticle = $xwGeshi->parse_code();
 +
}
 +
}
 +
}
 +
 +
# ---------------------------------------------------------------------------------------------------------------------- #
 +
# TRANSFORMS
 +
# - we should use DTD's for each kind: document, image, layout, table
 +
 +
function xwTransform_document_xxx() {
 +
# documents are built from parts,
 +
# the parts are a tree in its body
 +
# includes 'edit' link for each (like section, and also like table)
 +
}
 +
 +
# A document object is finalised by transforming it to its body's text
 +
function xwTransform_document_render() {
 +
global $xwArticle;
 +
$root = $xwArticle->document_element();
 +
$body = $root->get_elements_by_tagname('body');
 +
if (count($body)) $xwArticle = $body[0]->dump_mem(true);
 +
}
 +
 +
function xwTransform_layout_xxx() {
 +
# for layout container style article
 +
}
 +
 +
function xwTransform_image_xxx() {
 +
# object contains properties for loading and transforming an image
 +
# image needs no body
 +
 +
# Get the global image on which imageTransforms work
 +
global $xwArticleImage;
 +
}
 +
 +
# Converts the in-memory-working image into article content
 +
function xwTransform_image_render() {
 +
global $xwArticle;
 +
global $xwArticleTitle;
 +
global $xwArticleImage;
 +
global $xwRaw;
 +
if ($xwRaw) {
 +
# replace article object with image
 +
ob_start()
 +
imagePng($xwArticleImage);
 +
$xwArticle = ob_get_clean();
 +
# set header to image
 +
header("Content-type: image/png");
 +
}
 +
else {
 +
# the raw image is not being requested, render image in-page with info instead
 +
$xwArticle = "<img src=\"$xwArticleTitle?action=raw\" alt=\"$xwArticleTitle\"/>";
 +
}
 +
}
 +
 +
# A table object is an interface to a database table
 +
# - this can't be implimented fully until the 'edit' hook is done
 +
function xwTransform_table_xxx() {
 +
# - view lists the table/result with links to edit each (like a normal composition-doc)
 +
# - also form for create/edit/edlete
 
}
 
}
  
Line 223: Line 344:
 
# FUNCTIONS
 
# FUNCTIONS
  
# Retreive XML wiki-article and return as a DOM object
+
# Retreive wiki-article
# - DOM articles are cached in $xwArticleCache for reuse in recursive processing
+
# - A DOM object is returned if possible,
 +
# - or otherwise string content is returned (which can be parsed for highlighting)
 
function xwGetArticle($articleTitle) {
 
function xwGetArticle($articleTitle) {
 
# Return with results if already cached
 
# Return with results if already cached
Line 230: Line 352:
 
if (isset($xwArticleCache[$articleTitle])) return $xwArticleCache[$articleTitle];
 
if (isset($xwArticleCache[$articleTitle])) return $xwArticleCache[$articleTitle];
 
# Get wiki article content (XML)
 
# Get wiki article content (XML)
$articleXML = new Article(Title::newFromText($articleTitle));
+
$article = new Article(Title::newFromText($articleTitle));
$articleXML = $articleXML->getContent(false);
+
$article = $article->getContent(false);
# Convert to DOM object
+
# Convert to DOM object if possible
if (!$articleDOM = @domxml_open_mem($articleXML)) $articleDOM = domxml_new_doc("1.0");
+
if ($articleDOM = @domxml_open_mem($article)) $article = $articleDOM;
return $xwArticleCache[$articleTitle] = $articleDOM;
+
# Return content
 +
return $xwArticleCache[$articleTitle] = $article;
 
}
 
}
  
Line 243: Line 366:
 
}
 
}
  
# Render a xmlWiki system message
+
# Add message to queue
 
function xwMessage($msg, $col) {
 
function xwMessage($msg, $col) {
return "\n<table width=100% border=0><tr><td align=center>
+
global $xwMessages;
<table width=50% border bordercolor=#bbbbbb borderwidth=1 bgcolor=#999999><tr><td align=center>
+
$xwMessages[] = "<div class=\"xwMessage\"><font color=\"$col\">$msg</font></div>\n";
<font face=arial size=2 color=$col><b>$msg</b></font>
 
</table></table>\n";
 
 
}
 
}
  

Revision as of 06:55, 1 June 2005

<php> <?php

  1. xmlWiki - MediaWiki XML Hack
  2. Nad - 2005-05-18
  1. CSS STYLES
  2. the are accessed via http, so their article url can be referred to locally in the html
  3. - maybe make the default request 'raw' and must specifically request 'view'
  1. LATER:
  2. allow XIncludes to build large docs from others
  3. allow docBook and DSSSL content
  1. ---------------------------------------------------------------------------------------------------------------------- #
  2. SCRIPT CONTENTS
  1. INIT
  2. - do admin and exit if running directly
  3. - get wiki/request env
  4. - get article
  5. - permissions
  6. - build env (if action=raw, env is empty but a header is added)
  7. INPUT
  8. - validate xml and report error or,
  9. - process form-input (backslashes etc if necessary)
  10. OUTPUT
  11. - trap MediaWiki output
  12. - extract content and links
  13. - if view/preview/raw, do transform:
  14. - replace view/preview with transformed article
  15. - render output
  16. - if saving, foreach in publish-list,
  17. - do transform but with specified env
  18. - publish
  19. TRANSFORM
  20. - process dom-article (pass PT,XSLT list and DOM-article, returns DOM-result)
  21. - if docType is an xwArticle, see above
  22. TRANSFORMS
  23. - document transforms
  24. - image transforms
  25. - layout transforms
  26. - database table transforms
  27. FUNCTIONS
  28. - get article
  29. - etxract hrefs from text
  30. - message/log
  31. ADMIN
  32. - enable/disable patch
  1. ---------------------------------------------------------------------------------------------------------------------- #
  2. INIT
  1. 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 $xwArticleTitle = $wgTitle->mTextform; $xwArticle = xwGetArticle($xwArticleTitle); $xwDocType = null; $xwRoot = null;

$xwEdit = isset($_REQUEST['action'])&&($_REQUEST['action'] == 'edit'); $xwView = isset($_REQUEST['action'])&&($_REQUEST['action'] == 'view'); $xwRaw = isset($_REQUEST['action'])&&($_REQUEST['action'] == 'raw'); $xwPreview = isset($_REQUEST['wpPreview']); $xwSave = isset($_REQUEST['wpSave']);

$xwUserName = $wgUser->mName; $xwUserArticle = xwGetArticle("User:$xwUserName"); $xwReadable = true; $xwWritable = true;

$xwMessages = array(); $xwArticleCache = array(); $xwEnv = array();

# If article is an object, if (is_object($xwArticle)) { # Get doc info $xwDocType = $xwArticle->doctype->name; $xwRoot = $xwArticle->document_element(); # Get perms $xwUserGroups[] = $xwUserName; // This allows users to be specified in permissions-lists in addition to groups $xwReadable = null; # True if this article is readable by this user $xwWritable = null; # True if this article is writeable by this user }

# Build default transform environment (later from prefs, site etc) if ($xwRaw) { # Raw article is requested, so env is empty } else { # Create default environment (the name of another article) # - this does default transforms depending on type (eg highlighting for *.php) $xwEnv[] = ; }

}

  1. ---------------------------------------------------------------------------------------------------------------------- #
  2. INPUT
  1. No input processing for now
  1. Parse and process input from forms

function xwProcessInput() {

global $xwArticle; global $xwArticleTitle; global $xwRoot; global $xwDocType;

global $xwSave;

global $xwReadable; global $xwWritable;

# If article is being updated, if ($xwSave) { global $_POST; if (!$xwReadable || !$xwWritable) die("I'm sorry Dave, I'm afraid I can't do that."); }

}

  1. ---------------------------------------------------------------------------------------------------------------------- #
  2. OUTPUT
  1. Generate new output to send back to browser

function xwProcessOutput() {

global $wgOut;

global $xwArticle; global $xwArticleTitle; global $xwRoot; global $xwDocType;

global $xwView; global $xwPreview; global $xwSave;

global $xwUserName; global $xwUserArticle; global $xwReadable; global $xwWritable;

# First trap Wiki output and extract content and links (should use $ver like Admin Page) ob_start(); $wgOut->output(); $xwWikiOutput = ob_get_clean();

# Extract links (not used currently) $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();

# Security if (!$xwReadable) { # change output to access denied message if !readable } if (!$xwWritable) { # remove edit link }

# Transform article for raw request (ignores wiki-output completely) if ($xwRaw) $xwOutput = xwTransformArticle();

# Transform article for normal view if ($xwView) { if (preg_match('/^(.+).+(.+)$/m', $xwOutput, $xwMatch)) { $xwOutput = xwTransformArticle(); $xwOutput = $xwMatch[1].$xwOutput.$xwMatch[2]; } else xwMessage('xmlWiki couldn\'t match view-output!', 'red'); }

# Transform article for preview if ($xwPreview) { if (preg_match('/^(.+.+Remember.+saved!.+?<\\/p>).+(<script.+?<\\/script>.?<form id="editform".+.+)$/m', $xwOutput, $xwMatch)) { $xwOutput = xwTransformArticle(); $xwOutput = $xwMatch[1].$xwOutput.$xwMatch[2]; } else xwMessage('xmlWiki couldn\'t match preview-output!', 'red'); }

# Transform article for publishing if ($xwSave && is_object($xwArticle)) { # Get publish list $xwPublishList = $xwRoot->get_elements_by_tagname('publish'); if (count($xwPublishList)) $xwPublishList = $xwPublishList[0]->dump_mem(true); $xwPublishList = split(',', $xwPublishList); $xwOutput = xwTransformArticle(); # Publish each item foreach ($xwPublishList as $xwDestination) { if ($xwHandle = fopen($xwDestination, 'a')) { fwrite($xwHandle, $xwTransformedArticle); fclose($xwHandle); xwMessage("Article published to $cmDestination", 'green'); } else xwMessage("Failed to publish to $cmDestination", 'red'); } }

# Render final output and messages # - not good if content isn't plain-text anymore! foreach ($xwMessages as $msg) $xwOutput .= $msg; print $xwOutput; }

  1. ---------------------------------------------------------------------------------------------------------------------- #
  2. TRANSFORM

function xwTransformArticle() {

global $xwArticle; global $xwArticleTitle; global $xwDocType;

# If content is object, if (is_object($xwArticle)) { # we should check DTD's here for document, image, table, layout # 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"> if ($xwDocType == 'xmlwiki') { # Get the documents transforms # - the first transforms adjust the document while its still a DOM object # - but at some point it would normally transform to text, # - it may then have some further text-based transforms $xwTransforms = $root->get_elements_by_tagname('transform');

# - add php-transform-articles,CSS's & XSLT's to $xwEnv # - $xwEnv transforms first! }

# If object wasn't one of ours, or didn't get transformed to a string... if (!is_string($xwArticle)) { # validate, report errors

# apply stylesheet/XSLT if xml asks for one,

# Convert DOM back to XML $xwArticle = $xwArticle->dump_mem(true); } }

# Apply syntax highlighting if string (even if article was an object, it will be a string now) # - This isn't a transform because it also applies to non-object articles if (is_string($xwArticle)) { # First check for entire article highlighting if (ereg('\\.as$', $xwArticleTitle)) $xwLang = 'actionscript'; elseif (ereg('\\.py$', $xwArticleTitle)) $xwLang = 'python'; elseif (ereg('\\.java$', $xwArticleTitle)) $xwLang = 'java'; elseif (ereg('\\.(cpp)|(h)$', $xwArticleTitle)) $xwLang = 'cpp'; elseif (ereg('\\.js$', $xwArticleTitle)) $xwLang = 'javascript'; elseif (ereg('\\.css$', $xwArticleTitle)) $xwLang = 'css'; elseif (ereg('^#![/a-zA-Z0-9]+\\/perl', $xwArticle)) $xwLang = 'perl'; elseif (ereg('^#![/a-zA-Z0-9]+sh', $xwArticle)) $xwLang = 'bash'; elseif (ereg('^<?xml', $xwArticle)) $xwLang = 'xml'; elseif (ereg('^<?html', $xwArticle)) $xwLang = 'html4strict'; else { # Otherwise, parse article for internal highlights # <?,<% lang (default % is asp, default ? is php) # <script language= (default is javascript)

$xwLang = false; }

# Highlight entire article if xwLang has been set if ($xwLang) $xwGeshi = new GeSHi($xwArticle, $xwLang, "extensions/geshi/geshi"); $geshi->set_keywords_style(1, 'font-weight: 100;', true); $geshi->set_comments_style $geshi->set_escape_char_style $geshi->set_brackets_style $geshi->set_strings_style $geshi->set_numbers_style $geshi->set_methods_style $geshi->set_symbols_style $geshi->set_regexps_style $geshi->set_script_style $xwArticle = $xwGeshi->parse_code(); } } }

  1. ---------------------------------------------------------------------------------------------------------------------- #
  2. TRANSFORMS
  3. - we should use DTD's for each kind: document, image, layout, table

function xwTransform_document_xxx() { # documents are built from parts, # the parts are a tree in its body # includes 'edit' link for each (like section, and also like table) }

  1. A document object is finalised by transforming it to its body's text

function xwTransform_document_render() { global $xwArticle; $root = $xwArticle->document_element(); $body = $root->get_elements_by_tagname('body'); if (count($body)) $xwArticle = $body[0]->dump_mem(true); }

function xwTransform_layout_xxx() { # for layout container style article }

function xwTransform_image_xxx() { # object contains properties for loading and transforming an image # image needs no body

# Get the global image on which imageTransforms work global $xwArticleImage; }

  1. Converts the in-memory-working image into article content

function xwTransform_image_render() { global $xwArticle; global $xwArticleTitle; global $xwArticleImage; global $xwRaw; if ($xwRaw) { # replace article object with image ob_start() imagePng($xwArticleImage); $xwArticle = ob_get_clean(); # set header to image header("Content-type: image/png"); } else { # the raw image is not being requested, render image in-page with info instead $xwArticle = "<img src=\"$xwArticleTitle?action=raw\" alt=\"$xwArticleTitle\"/>"; } }

  1. A table object is an interface to a database table
  2. - this can't be implimented fully until the 'edit' hook is done

function xwTransform_table_xxx() { # - view lists the table/result with links to edit each (like a normal composition-doc) # - also form for create/edit/edlete }

  1. ---------------------------------------------------------------------------------------------------------------------- #
  2. FUNCTIONS
  1. Retreive wiki-article
  2. - A DOM object is returned if possible,
  3. - or otherwise string content is returned (which can be parsed for highlighting)

function xwGetArticle($articleTitle) { # Return with results if already cached global $xwArticleCache; if (isset($xwArticleCache[$articleTitle])) return $xwArticleCache[$articleTitle]; # Get wiki article content (XML) $article = new Article(Title::newFromText($articleTitle)); $article = $article->getContent(false); # Convert to DOM object if possible if ($articleDOM = @domxml_open_mem($article)) $article = $articleDOM; # Return content return $xwArticleCache[$articleTitle] = $article; }

  1. Return a list of the hrefs found in the passed content

function xwExtractHrefs($content) { preg_match_all('/(<a.+?<\/a>)/', $content, $match); return $match[1]; }

  1. Add message to queue

function xwMessage($msg, $col) { global $xwMessages;

$xwMessages[] = "

$msg

\n";

}

  1. ---------------------------------------------------------------------------------------------------------------------- #
  2. ADMIN

function xwAdminPage() {

?>xmlWiki Admin Page

xmlWiki
xmlWiki Admin Page





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. [ enable ]', '#003366'); else print xwMessage('xmlWiki is currently enabled. [ disable ]', '#003366'); ?>


XHTML1.0 PHP MediaWiki



<? }

?> </php>