Difference between revisions of "Xmlwiki.php"
(Shyit, that broke it real bad... try this...) |
(Revert moving properties-merge - breaking things real bad :-() |
||
Line 49: | Line 49: | ||
# Get default properties article | # Get default properties article | ||
− | $xwDefaultProperties = xwDomificateArticle( xwArticleContent( 'default-properties.xml' ), 'defaults' ); | + | $xwDefaultProperties = xwDomificateArticle(xwArticleContent('default-properties.xml'), 'defaults'); |
# Get user-system-article and extract users' groups from it if any | # Get user-system-article and extract users' groups from it if any | ||
− | $xwUserSYS = xwArticleContent( "sys:$xwUserName" ); | + | $xwUserSYS = xwArticleContent("sys:$xwUserName"); |
− | xwDomificateArticle( $xwUserSYS, "sys:$xwUserName" ); | + | xwDomificateArticle($xwUserSYS, "sys:$xwUserName"); |
− | $xwUserGroups = array_merge( $xwUserGroups, xwGetListByTagname( $xwUserSYS, 'groups' ) ); | + | $xwUserGroups = array_merge($xwUserGroups, xwGetListByTagname($xwUserSYS, 'groups')); |
# Read user-prefs | # Read user-prefs | ||
− | xwGetProperty( $xwUserSYS, 'xpath:/user/debug', $xwDebug ); | + | xwGetProperty($xwUserSYS, 'xpath:/user/debug', $xwDebug); |
# Get article-meta-file and extract article-perms | # Get article-meta-file and extract article-perms | ||
− | if ( $xwIsSystem ) $xwArticleReadableBy = $xwArticleWritableBy = array( 'admin' ); | + | if ($xwIsSystem) $xwArticleReadableBy = $xwArticleWritableBy = array('admin'); |
else { | else { | ||
# Get xml:article (self if already xml:*) | # Get xml:article (self if already xml:*) | ||
− | $xwArticleProperties = xwArticleProperties( $xwArticleTitle ); | + | if ($xwArticleProperties = $xwIsProperties ? xwDomificateArticle($xwArticle) : xwArticleProperties($xwArticleTitle)) |
− | $xwArticleReadableBy = xwGetListByTagname( $xwArticleProperties, 'read' ); | + | |
− | $xwArticleWritableBy = xwGetListByTagname( $xwArticleProperties, 'write' ); | + | # Merge default-properties into article-properties object |
− | if ( $xwIsProperties ) $xwArticleProperties = false; | + | if (is_object($xwArticleProperties)) xwMergeDOM($xwArticleProperties, $xwDefaultProperties); |
+ | else $xwArticleProperties = $xwDefaultProperties; | ||
+ | |||
+ | $xwArticleReadableBy = xwGetListByTagname($xwArticleProperties, 'read'); | ||
+ | $xwArticleWritableBy = xwGetListByTagname($xwArticleProperties, 'write'); | ||
+ | if ($xwIsProperties) $xwArticleProperties = false; | ||
} | } | ||
− | if ( $xwIsSpecial || !count( $xwArticleReadableBy ) ) $xwArticleReadableBy = array( 'anyone' ); | + | if (!is_object($xwArticleProperties)) $xwArticleProperties = $xwDefaultProperties; |
− | if ( !count( $xwArticleWritableBy ) ) $xwArticleWritableBy = array( 'anyone' ); | + | if ($xwIsSpecial || !count($xwArticleReadableBy)) $xwArticleReadableBy = array('anyone'); |
+ | if (!count($xwArticleWritableBy)) $xwArticleWritableBy = array('anyone'); | ||
# If no language specified in properties, guess from name and content | # If no language specified in properties, guess from name and content | ||
Line 358: | Line 364: | ||
# Return properties object from title | # Return properties object from title | ||
# - returns self if already a properties article | # - returns self if already a properties article | ||
− | |||
function xwArticleProperties( $articleTitle, $xmlself = true ) { | function xwArticleProperties( $articleTitle, $xmlself = true ) { | ||
− | global $xwDebug | + | global $xwDebug; |
− | if ( $xwDebug ) xwMessage( "xwArticleProperties(\"$articleTitle\")", 'blue' ); | + | if ($xwDebug) xwMessage("xwArticleProperties(\"$articleTitle\")",'blue'); |
− | $id = ( $xmlself && eregi( '^xml:', $articleTitle ) ) ? $articleTitle : 'xml:'.ucfirst( $articleTitle ); | + | $id = ( $xmlself && eregi( '^xml:', $articleTitle ) ) ? $articleTitle : 'xml:'.ucfirst($articleTitle); |
− | if ( !$properties = xwArticleContent( $id, false ) ) $properties = | + | if ( !$properties = xwArticleContent( $id, false ) ) $properties = |
'<?xml version="1.0" standalone="yes"?> | '<?xml version="1.0" standalone="yes"?> | ||
<!DOCTYPE xmlwiki:properties SYSTEM "xmlwiki-properties.dtd"> | <!DOCTYPE xmlwiki:properties SYSTEM "xmlwiki-properties.dtd"> | ||
<properties/>'; | <properties/>'; | ||
− | xwDomificateArticle( $properties, $id ) | + | return xwDomificateArticle( $properties, $id ); |
− | |||
− | |||
} | } | ||
Revision as of 06:10, 15 March 2006
- xmlWiki - MediaWiki XML Hack
- Nad - Started: 2005-05-18
- Exit if not included from index.php
defined('MEDIAWIKI') or die('xmlwiki.php must be included from MediaWiki\'s index.php!'); if (php(3)) die('xmlWiki cannot run on less than PHP4!');
- Add the rest of the hooks
$wgHooks['PreParser'][] = 'xwPreParserHook'; $wgHooks['ParserBeforeStrip'][] = 'xwPreParserHook'; $wgHooks['PostParser'][] = 'xwPostParserHook'; $wgHooks['ParserAfterTidy'][] = 'xwPostParserHook'; $wgHooks['Input'][] = 'xwInputHook'; $wgHooks['Output'][] = 'xwOutputHook';
- System globals
$xwDebug = false; $xwMessages = array(); $xwArticleCache = array(); $xwStyleSheets = array(); $xwTemplate = null; $xwParserHookCalled = false; $xwSkinHookCalled = false; $xwMsgToken = ; $xwCssToken = ; $xwScript = $wgScript;
- User globals
$xwUserName = ucwords($wgUser->mName); $xwUserSYS = null; $xwUserGroups = array($xwUserName, 'anyone'); $xwEdit = isset($_REQUEST['action']) && ($_REQUEST['action'] == 'edit'); $xwView = (!isset($_REQUEST['action']) || (isset($_REQUEST['action']) && ($_REQUEST['action'] == 'view'))); $xwRaw = isset($_REQUEST['action']) && ($_REQUEST['action'] == 'raw'); $xwPreview = isset($_REQUEST['wpPreview']); $xwSave = isset($_REQUEST['wpSave']);
- Article globals
$xwArticleTitle = $wgTitle->getPrefixedText(); $xwArticle = $xwPreview ? $wgRequest->gettext('wpTextbox1') : $wgArticle->getContent(false); $xwArticleProperties = null; $xwIsProperties = preg_match('/^xml:.+$/i', $xwArticleTitle); $xwIsSystem = preg_match('/^sys:.+$/i', $xwArticleTitle); $xwIsUser = preg_match('/^user:.+$/i', $xwArticleTitle); $xwIsSpecial = preg_match('/^special:.+$/i', $xwArticleTitle); $xwIsAdmin = false; $xwArticleReadableBy = null; $xwArticleWritableBy = null;
- Get default properties article
$xwDefaultProperties = xwDomificateArticle(xwArticleContent('default-properties.xml'), 'defaults');
- Get user-system-article and extract users' groups from it if any
$xwUserSYS = xwArticleContent("sys:$xwUserName"); xwDomificateArticle($xwUserSYS, "sys:$xwUserName"); $xwUserGroups = array_merge($xwUserGroups, xwGetListByTagname($xwUserSYS, 'groups'));
- Read user-prefs
xwGetProperty($xwUserSYS, 'xpath:/user/debug', $xwDebug);
- Get article-meta-file and extract article-perms
if ($xwIsSystem) $xwArticleReadableBy = $xwArticleWritableBy = array('admin'); else { # Get xml:article (self if already xml:*) if ($xwArticleProperties = $xwIsProperties ? xwDomificateArticle($xwArticle) : xwArticleProperties($xwArticleTitle))
# Merge default-properties into article-properties object if (is_object($xwArticleProperties)) xwMergeDOM($xwArticleProperties, $xwDefaultProperties); else $xwArticleProperties = $xwDefaultProperties;
$xwArticleReadableBy = xwGetListByTagname($xwArticleProperties, 'read'); $xwArticleWritableBy = xwGetListByTagname($xwArticleProperties, 'write'); if ($xwIsProperties) $xwArticleProperties = false; } if (!is_object($xwArticleProperties)) $xwArticleProperties = $xwDefaultProperties; if ($xwIsSpecial || !count($xwArticleReadableBy)) $xwArticleReadableBy = array('anyone'); if (!count($xwArticleWritableBy)) $xwArticleWritableBy = array('anyone');
- If no language specified in properties, guess from name and content
if (!xwGetProperty($xwArticleProperties, 'language', $xwLanguage)) xwSetProperty($xwArticleProperties, 'language', xwArticleType($xwArticleTitle, $xwArticle));
- Set perms for this request
if ($xwDebug) xwMessage('PERMISSIONS:','green'); if (in_array('admin', $xwUserGroups)) $xwIsAdmin = $xwReadable = $xwWritable = true; else { $xwReadable = 0 < count(array_intersect($xwArticleReadableBy, $xwUserGroups)); $xwWritable = 0 < count(array_intersect($xwArticleWritableBy, $xwUserGroups)); } if ($xwDebug) { xwMessage('Groups: '.join(', ', $xwUserGroups)); xwMessage('Readable ('.($xwReadable?'yes':'no').'): '.join(', ', $xwArticleReadableBy)); xwMessage('Writable ('.($xwWritable?'yes':'no').'): '.join(', ', $xwArticleWritableBy)); }
- Divert to access-denied article if not readable
if (!$xwReadable) { $action = 'view'; $xwSave = $xwEdit = false; }
- Handle security for Move
if (!$xwIsAdmin and ($target = $_REQUEST['target']) ) { if ($xwArticleProperties = new Article(Title::newFromText("xml:$target"))) $xwArticleProperties = $xwArticleProperties->getContentWithoutUsingSoManyDamnGlobals(); $writableBy = xwGetListByTagname(xwDomificateArticle($xwArticleProperties), 'write'); if (!count($writableBy)) $writableBy = array('anyone'); if (!count(array_intersect($writableBy, $xwUserGroups))) { $xwArticleTitle = $target; xwMessage("Sorry article \"$xwArticleTitle\" not movable!",'red'); $wgArticle = new Article($wgTitle = Title::newFromText($target)); $xwArticle = $wgArticle->getContent(false); } }
- Apply init transforms
xwReduceTransformStack( $xwArticle, $xwArticleProperties, $xwArticleTitle, 'init', 'INIT-HOOK' );
- ---------------------------------------------------------------------------------------------------------------------- #
- INPUT HOOK
- Parse and process input from forms
function xwInputHook() {
global $xwArticle, $xwArticleProperties, $xwArticleTitle, $xwWritable, $_REQUEST; global $xwDebug, $xwSave, $xwEdit, $action, $xwUserName, $wgArticle, $wgTitle; global $xwUserGroups, $xwIsProperties, $xwIsSystem, $xwIsAdmin; if ($xwDebug) xwMessage('INPUT-HOOK:','green');
# If not writable, change action to view if ( !$xwWritable && !in_array($action, array('view','history','raw')) ) { xwMessage('Sorry, article not writable, action changed to "view".', 'red'); $action = 'view'; $xwSave = $xwEdit = false; }
# Scan POST and apply any XPath inputs foreach ( $_REQUEST as $query => $value ) { if ( ereg('^xpath.3A.+.3A', $query) ) $query = urldecode( $query ); if ( ereg('^xpath:.+:', $query) ) xwSetProperty( $xwArticleProperties, $query, $value ); }
# if saving a pseudo-namespace... if ($xwSave) { if ( $xwIsProperties || $xwIsSystem ) { # wpTextbox1 should be valid XML to be saved $tb = $_REQUEST['wpTextbox1']; xwDomificateArticle( $tb, 'POST-DATA' ); if ( !is_object($tb) ) { xwMessage('A meta-article must be valid XML! article not saved.', 'red'); $action = 'view'; $xwSave = $xwEdit = false; } elseif ( $xwIsProperties && !$xwIsAdmin ) { foreach ( xwGetListByTagname($tb, 'write') as $perm ) { if ( !in_array( $perm, $xwUserGroups ) ) { xwMessage("Only members of \"$perm\" can set permissions for \"$perm\"! article not saved.", 'red'); $action = 'view'; $xwSave = $xwEdit = false; } } } } }
}
- ---------------------------------------------------------------------------------------------------------------------- #
- OUTPUT HOOK
- Post-process and output article
function xwOutputHook() {
global $wgUser, $xwUserName, $wgOut, $xwDebug, $xwIsProperties, $xwIsSystem, $xwIsAdmin; global $xwArticle, $xwArticleProperties, $xwArticleTitle, $xwEdit, $action; if ($action == 'raw') return; if ($xwDebug) xwMessage('OUTPUT-HOOK:','green');
# Activate the skin-hook and generate wiki's output $wgUser->setOption('skin', 'xwskin'); $wgOut->output();
# Editing article if ($xwEdit && preg_match("/^(.*<textarea .+?>)\\s*(<\\/textarea>.*)$/s", $xwArticle, $m)) { # If editing an empty sys:article or xml:article, add default content if ($xwIsSystem) { $xwArticle = $m[1]."<?xml version=\"1.0\" standalone=\"yes\"?>\n"; $xwArticle .= "<!DOCTYPE xmlwiki:user SYSTEM \"xmlwiki-user.dtd\">\n"; $xwArticle .= "<user>\n\t<groups></groups>\n</user>\n".$m[2]; xwMessage('Note: There is currently no content for this system article, default content has been generated','red'); } elseif ($xwIsProperties) { $a = xwArticleContent( str_replace( 'Xml:', , $xwArticleTitle ) ); if ( preg_match("/\\[\\[Category:(.+?)]]/", $a, $n) && $xwArticle = xwArticleProperties('Category:'.$n[1]) ) { xwUndomificateArticle( $xwArticle ); xwMessage('Note: This article has no properties, default content has been inherited from Xml:'.$n[1], 'red'); } else { xwMessage('Note: This article has no properties, a general default has been generated', 'red'); $xwArticle = "<?xml version=\"1.0\" standalone=\"yes\"?>\n"; $xwArticle .= "<!DOCTYPE xmlwiki:properties SYSTEM \"xmlwiki-properties.dtd\">\n"; $xwArticle .= "<properties>\n\t<read>anyone</read>\n\t<write>$xwUserName</write>\n"; $xwArticle .= "\t<language></language>\n\t<category></category>\n\t\n\t<view></view>\n\t<edit></edit>\n\t<save></save>\n</properties>\n"; } $xwArticle = $m[1].$xwArticle.$m[2]; } } elseif ( $xwEdit ) { # Editing normally, apply transforms in edit-list xwReduceTransformStack( $xwArticle, $xwArticleProperties, $xwArticleTitle, 'edit', 'OUTPUT-HOOK' ); }
if ( $xwDebug ) { global $xwParserHookCalled, $xwSkinHookCalled; if ( !$xwParserHookCalled ) xwMessage( 'PARSER-HOOK was not called', 'green' ); if ( !$xwSkinHookCalled ) xwMessage( 'SKIN-HOOK was not called', 'green' ); }
# Insert stylesheets and messages into output xwReplaceTokens( $xwArticle );
# Permhack: remove private info if search result if ( isset($_REQUEST['search']) && !$xwIsAdmin ) $xwArticle = preg_replace_callback(
'/
- ---------------------------------------------------------------------------------------------------------------------- #
- PRE-PARSER HOOK
- ---------------------------------------------------------------------------------------------------------------------- #
- POST-PARSER HOOK
- ---------------------------------------------------------------------------------------------------------------------- #
- SKIN HOOK
- If attempted xml encountered, try to domificate and transform
- - Raw requests don't get here
- ---------------------------------------------------------------------------------------------------------------------- #
- ARTICLE FUNCTIONS
- - these all use super-globals since they can be called from within evals
- Return true if passed title readable/writable by current user
- Retreive wiki-article as raw text
- Return properties object from title
- - returns self if already a properties article
- Decide kind of article from content and title
- Convert passed article to a DOM object
- - Article is unchanged if not valid XML
- Reduce article to a string if it's a DOM object
- - ie if all xslt's had xml-output-method
- ---------------------------------------------------------------------------------------------------------------------- #
- TRANSFORM FUNCTIONS
- Apply all transforms in passed stack
- Apply a transform
- Apply PHP-transform if article perms are only writable by admin or dev
- Append CSS stylesheet link to output
- Apply XSLT to article-dom
- - if article is not and object, the XSLT will be appended to the stylesheet-ref list like a CSS
- - if output-method is html, article will get stringified and language updated
- ---------------------------------------------------------------------------------------------------------------------- #
- DOM FUNCTIONS
- Return result set of an XPath query on passed DOM-object
- - Syntax: xpath:XPathQuery:[[@]node][+] = value
- - if "node" exists, then a new element (or att if "@node") is created for the value
- - if "+" exists, content is appended, else replaced
- Return array of comma-separated-items in element content
- - if more than one element all are split and appended into the list
- Merge the two passed DOM objects
- - appends, does not overwrite
- Remove all occourences of a certain element
- ---------------------------------------------------------------------------------------------------------------------- #
- UTILITY FUNCTIONS
- Extract error-messages from captured output and put in proper message-queue
- Add message to queue
There are Messages
$article = str_replace($xwMsgToken, $msg, $article); } }
- Print list of passed object's methods and properties
function xwCheckoutObject($obj) {
if (is_object($obj)) {
print strtoupper("
$obj properties:
");
foreach (get_object_vars($obj) as $k=>$v) print htmlentities("$k => $v")."
";
print strtoupper("
$obj methods:
");
foreach (get_class_methods($obj) as $k=>$v) print "$v
";
}
if (is_array($obj)) {
print strtoupper("
Array content:
");
foreach ($obj as $k=>$v) print "$k => $v
";
}
die;
}
- Return true if PHP major version equals passed int
- - needed due to different DOM implimentation on 4 and 5 (and none on 3)
function php($ver) { return substr(phpversion(),0,1) == "$ver"; }