r101327 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r101326‎ | r101327 | r101328 >
Date:23:28, 30 October 2011
Author:ning
Status:deferred
Tags:
Comment:
* apply paragraph object model to WOM set
* apply (template) field place holder object model
* apply query result to WOM api
* some bug fixing stuff
Modified paths:
  • /trunk/extensions/WikiObjectModel/includes/WOM_Processor.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/WOM_Setup.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/apis/WOM_OM_QueryResult.php (added) (history)
  • /trunk/extensions/WikiObjectModel/includes/apis/WOM_OutputObjectModel.php (added) (history)
  • /trunk/extensions/WikiObjectModel/includes/apis/WOM_OutputProcessor.php (added) (history)
  • /trunk/extensions/WikiObjectModel/includes/apis/WOM_Query.php (added) (history)
  • /trunk/extensions/WikiObjectModel/includes/apis/WOM_SetObjectModel.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Category.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_HTMLTag.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_ListItem.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Paragraph.php (added) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_ParamValue.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Parameter.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_ParserFunction.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Property.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Section.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Table.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_TblCell.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Template.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WOM_OM_TmplFieldHolder.php (added) (history)
  • /trunk/extensions/WikiObjectModel/includes/models/WikiObjectModel.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/parsers/WOMParamValueParser.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/parsers/WOMPropertyParser.php (modified) (history)
  • /trunk/extensions/WikiObjectModel/includes/parsers/WOMTemplateFieldHolderParser.php (added) (history)
  • /trunk/extensions/WikiObjectModel/includes/parsers/WOMTemplateParser.php (modified) (history)

Diff [purge]

Index: trunk/extensions/WikiObjectModel/includes/parsers/WOMTemplateParser.php
@@ -15,7 +15,7 @@
1616
1717 public function parseNext( $text, WikiObjectModelCollection $parentObj, $offset = 0 ) {
1818 $text = substr( $text, $offset );
19 - $r = preg_match( '/^(\{\{([^|}]+))([|}])/', $text, $m );
 19+ $r = preg_match( '/^(\{\{([^{|}]+))([|}])/', $text, $m );
2020
2121 if ( $r ) {
2222 if ( !preg_match( '/[^' . Title::legalChars() . ']/', trim( $m[2] ) ) )
Index: trunk/extensions/WikiObjectModel/includes/parsers/WOMParamValueParser.php
@@ -14,7 +14,8 @@
1515 }
1616
1717 public function parseNext( $text, WikiObjectModelCollection $parentObj, $offset = 0 ) {
18 - if ( !( $parentObj instanceof WOMParameterModel ) )
 18+ if ( !( ( $parentObj instanceof WOMParameterModel )
 19+ || ( $parentObj instanceof WOMTemplateFieldHolderModel ) ) )
1920 return null;
2021
2122 return array( 'len' => 0, 'obj' => new WOMParamValueModel() );
Index: trunk/extensions/WikiObjectModel/includes/parsers/WOMTemplateFieldHolderParser.php
@@ -0,0 +1,44 @@
 2+<?php
 3+/**
 4+ * @author Ning
 5+ *
 6+ * @file
 7+ * @ingroup WikiObjectModels
 8+ */
 9+
 10+class WOMTemplateFieldHolderParser extends WikiObjectModelParser {
 11+
 12+ public function __construct() {
 13+ parent::__construct();
 14+ $this->m_parserId = WOM_PARSER_ID_TEMPLATE_FIELD_HOLDER;
 15+ }
 16+
 17+ public function parseNext( $text, WikiObjectModelCollection $parentObj, $offset = 0 ) {
 18+ $text = substr( $text, $offset );
 19+ $r = preg_match( '/^(\{\{\{([^{|}]+))([|}])/', $text, $m );
 20+
 21+ if ( $r ) {
 22+ if ( !preg_match( '/[^' . Title::legalChars() . ']/', trim( $m[2] ) ) )
 23+// if(!preg_match(Title::getTitleInvalidRegex(), trim($m[2])))
 24+ return array( 'len' => ( $m[3] == '|' ) ? strlen( $m[0] ) : strlen( $m[1] ), 'obj' => new WOMTemplateFieldHolderModel( trim( $m[2] ) ) );
 25+ }
 26+ return null;
 27+ }
 28+
 29+ public function getSubParserID() {
 30+ return WOM_PARSER_ID_PARAM_VALUE;
 31+ }
 32+
 33+ public function isObjectClosed( $obj, $text, $offset ) {
 34+ if ( !$obj instanceof WOMTemplateFieldHolderModel ) return false;
 35+
 36+ if ( ( strlen( $text ) >= $offset + 3 )
 37+ && $text { $offset } == '}'
 38+ && $text { $offset + 1 } == '}'
 39+ && $text { $offset + 2 } == '}' ) {
 40+ return 3;
 41+ }
 42+
 43+ return false;
 44+ }
 45+}
Index: trunk/extensions/WikiObjectModel/includes/parsers/WOMPropertyParser.php
@@ -24,7 +24,9 @@
2525 // copied from SemanticMediaWiki, includes/SMW_ParserExtensions.php
2626 // not deal with <nowiki>, could be bug here. SMW has the same bug
2727 // E.g., [[text::this <nowiki> is ]] </nowiki> not good]]
28 - $semanticLinkPattern = '/^\[\[ # Beginning of the link
 28+// global $smwgLinksInValues;
 29+// if ( $smwgLinksInValues ) { // More complex regexp -- lib PCRE may cause segfaults if text is long :-(
 30+ $semanticLinkPattern = '/^\[\[ # Beginning of the link
2931 (?:([^:][^]]*):[=:])+ # Property name (or a list of those)
3032 ( # After that:
3133 (?:[^|\[\]] # either normal text (without |, [ or ])
@@ -34,7 +36,13 @@
3537 (?:\|([^]]*))? # Display text (like "text" in [[link|text]]), optional
3638 \]\] # End of link
3739 /xu';
38 -
 40+// } else { // Simpler regexps -- no segfaults found for those, but no links in values.
 41+// $semanticLinkPattern = '/\[\[ # Beginning of the link
 42+// (?:([^:][^]]*):[=:])+ # Property name (or a list of those)
 43+// ([^\[\]]*) # content: anything but [, |, ]
 44+// \]\] # End of link
 45+// /xu';
 46+// }
3947 $r = preg_match( $semanticLinkPattern, $text, $m );
4048 if ( $r ) {
4149 return array( 'len' => strlen( $m[0] ), 'obj' => new WOMPropertyModel( $m[1], $m[2], isset( $m[3] ) ? $m[3] : '' ) );
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Category.php
@@ -38,6 +38,6 @@
3939 }
4040
4141 protected function getXMLContent() {
42 - return $this->m_name;
 42+ return self::xml_entities( $this->m_name );
4343 }
4444 }
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_TmplFieldHolder.php
@@ -0,0 +1,44 @@
 2+<?php
 3+/**
 4+ * This model implements Template Field Holder models.
 5+ *
 6+ * @author Ning
 7+ * @file
 8+ * @ingroup WikiObjectModels
 9+ *
 10+ */
 11+
 12+class WOMTemplateFieldHolderModel extends WikiObjectModelCollection {
 13+ protected $m_key;
 14+
 15+ public function __construct( $key ) {
 16+ parent::__construct( WOM_TYPE_TMPL_FIELD_HOLDER );
 17+ $this->m_key = $key;
 18+ }
 19+
 20+ public function getKey() {
 21+ return $this->m_key;
 22+ }
 23+
 24+ public function getWikiText() {
 25+ return "{{{{$this->m_key}|{$this->getValueText()}}}}";
 26+ }
 27+
 28+ public function getValueText() {
 29+ return parent::getWikiText();
 30+ }
 31+
 32+ public function setXMLAttribute( $key, $value ) {
 33+ if ( $value == '' ) throw new MWException( __METHOD__ . ": value cannot be empty" );
 34+
 35+ if ( $key == 'name' ) {
 36+ $this->m_key = $value;
 37+ } else {
 38+ throw new MWException( __METHOD__ . ": invalid key/value pair: name|value_if_blank" );
 39+ }
 40+ }
 41+
 42+ protected function getXMLAttributes() {
 43+ return 'name="' . self::xml_entities( $this->m_key ) . '"';
 44+ }
 45+}
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Parameter.php
@@ -41,6 +41,6 @@
4242 }
4343
4444 protected function getXMLAttributes() {
45 - return "key=\"{$this->m_key}\"";
 45+ return 'key="' . self::xml_entities( $this->m_key ) . '"';
4646 }
4747 }
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_TblCell.php
@@ -33,7 +33,7 @@
3434 public function setXMLAttribute( $key, $value ) {
3535 if ( $value == '' ) throw new MWException( __METHOD__ . ": value cannot be empty" );
3636
37 - $value = str_replace( '\n', "\n", $value );
 37+// $value = str_replace( '\n', "\n", $value );
3838 if ( $key == 'prefix' ) {
3939 $this->m_prefix = $value;
4040 return;
@@ -42,8 +42,8 @@
4343 }
4444
4545 protected function getXMLAttributes() {
46 - $prefix = str_replace( "\n", '\n', $this->m_prefix );
 46+// $prefix = str_replace( "\n", '\n', $this->m_prefix );
4747 $prefix = str_replace( '"', "'", $prefix );
48 - return "prefix=\"{$prefix}\"";
 48+ return 'prefix="' . self::xml_entities( $prefix ) . '"';
4949 }
5050 }
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Property.php
@@ -11,6 +11,8 @@
1212 class WOMPropertyModel extends WikiObjectModel {
1313 protected $m_property; // name
1414 protected $m_smwdatavalue; // value, caption, type
 15+ protected $m_value;
 16+ protected $m_caption;
1517 protected $m_visible;
1618
1719 public function __construct( $property, $value, $caption = '' ) {
@@ -22,10 +24,20 @@
2325 }
2426
2527 $property = SMWPropertyValue::makeUserProperty( $property );
26 - $smwdatavalue = SMWDataValueFactory::newPropertyObjectValue( $property, $value, $caption );
 28+ $smwdatavalue = null;
 29+ // FIXME: property should be collection object according to templates
 30+ // if template/field used
 31+ if ( preg_match( '/\{\{.+\}\}/s', $value . $caption ) ) {
 32+ $value = "{$value}|{$caption}";
 33+ $caption = '';
 34+ } else {
 35+ $smwdatavalue = SMWDataValueFactory::newPropertyObjectValue( $property, $value, $caption );
 36+ }
2737
2838 $this->m_property = $property;
2939 $this->m_smwdatavalue = $smwdatavalue;
 40+ $this->m_value = $value;
 41+ $this->m_caption = $caption;
3042 $this->m_visible = !preg_match( '/\s+/', $caption );
3143 }
3244
@@ -63,11 +75,11 @@
6476 }
6577
6678 public function getPropertyValue() {
67 - return $this->m_smwdatavalue->getWikiValue();
 79+ return $this->m_smwdatavalue == null ? $this->m_value : $this->m_smwdatavalue->getWikiValue();
6880 }
6981
7082 public function getCaption() {
71 - $caption = $this->m_smwdatavalue->getShortWikiText();
 83+ $caption = $this->m_smwdatavalue == null ? $this->m_caption : $this->m_smwdatavalue->getShortWikiText();
7284 return ( $caption == $this->getPropertyValue() ) ? '' : $caption;
7385 }
7486
@@ -81,12 +93,12 @@
8294 }
8395 }
8496 protected function getXMLAttributes() {
85 - return "name=\"{$this->getPropertyName()}\"";
 97+ return 'name="' . self::xml_entities( $this->getPropertyName() ) . '"';
8698 }
8799 protected function getXMLContent() {
88100 return "
89 -<value>{$this->getPropertyValue()}</value>
90 -<caption>{$this->getCaption()}</caption>
 101+<value><![CDATA[{$this->getPropertyValue()}]]></value>
 102+<caption><![CDATA[{$this->getCaption()}]]></caption>
91103 ";
92104 }
93105 }
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Table.php
@@ -26,7 +26,8 @@
2727 }
2828
2929 public function getWikiText() {
30 - return "{| {$this->m_style}" . parent::getWikiText() . "\n|}";
 30+ return ( $this->isLastLF() ? '' : "\n" ) .
 31+ "{| {$this->m_style}" . parent::getWikiText() . "\n|}";
3132 }
3233
3334 public function setXMLAttribute( $key, $value ) {
@@ -38,7 +39,6 @@
3940 }
4041
4142 protected function getXMLAttributes() {
42 - $style = str_replace( '"', "'", $this->m_style );
43 - return "style=\"{$style}\"";
 43+ return 'style="' . self::xml_entities( str_replace( '"', "'", $this->m_style ) ) . '"';
4444 }
4545 }
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_ListItem.php
@@ -22,7 +22,8 @@
2323 }
2424
2525 public function getWikiText() {
26 - return $this->m_header . parent::getWikiText();
 26+ return ( $this->isLastLF() ? '' : "\n" ) .
 27+ $this->m_header . parent::getWikiText();
2728 }
2829
2930 public function setXMLAttribute( $key, $value ) {
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_ParamValue.php
@@ -17,8 +17,4 @@
1818 public function setXMLAttribute( $key, $value ) {
1919 throw new MWException( __METHOD__ . ": no key/value pair required" );
2020 }
21 -
22 - protected function getXMLAttributes() {
23 - return '';
24 - }
2521 }
Index: trunk/extensions/WikiObjectModel/includes/models/WikiObjectModel.php
@@ -66,6 +66,30 @@
6767 return $this->m_typeid;
6868 }
6969
 70+ public function getPreviousObject() {
 71+ $p = $this->getParent();
 72+ if ( $p == null ) return $p;
 73+
 74+ $previous = null;
 75+ foreach ( $p->getObjects() as $v ) {
 76+ if ( $this->getObjectID() == $v->getObjectID() ) {
 77+ return $previous;
 78+ }
 79+ $previous = $v;
 80+ }
 81+ return null;
 82+ }
 83+
 84+ protected function isLastLF() {
 85+ $pre = $this->getPreviousObject();
 86+ if ( $pre != null ) {
 87+ $wiki = $pre->getWikiText();
 88+ $len = strlen( $wiki );
 89+ return ( $len == 0 || $wiki { $len - 1 } == "\n" );
 90+ }
 91+ return true;
 92+ }
 93+
7094 /**
7195 * Return TRUE if a value was defined and understood by the given type,
7296 * and false if parsing errors occured or no value was given.
@@ -107,4 +131,39 @@
108132 }
109133
110134 public function objectUpdate( WikiObjectModel $obj ) { }
 135+
 136+ static function xml_entity_decode( $text, $charset = 'Windows-1252' ) {
 137+ // Double decode, so if the value was &amp;trade; it will become Trademark
 138+ $text = html_entity_decode( $text, ENT_COMPAT, $charset );
 139+ $text = html_entity_decode( $text, ENT_COMPAT, $charset );
 140+
 141+ return $text;
 142+ }
 143+
 144+ static function xml_entities( $text, $charset = 'Windows-1252' ) {
 145+ // First we encode html characters that are also invalid in xml
 146+ $text = htmlentities( $text, ENT_COMPAT, $charset, false );
 147+ // XML character entity array from Wiki
 148+ // Note: &apos; is useless in UTF-8 or in UTF-16
 149+ $arr_xml_special_char = array( "&quot;", "&amp;", "&apos;", "&lt;", "&gt;" );
 150+ // Building the regex string to exclude all strings with xml special char
 151+ $arr_xml_special_char_regex = "(?";
 152+
 153+ foreach ( $arr_xml_special_char as $key => $value ) {
 154+ $arr_xml_special_char_regex .= "(?!$value)";
 155+ }
 156+ $arr_xml_special_char_regex .= ")";
 157+
 158+ // Scan the array for &something_not_xml; syntax
 159+ $pattern = "/$arr_xml_special_char_regex&([a-zA-Z0-9]+;)/";
 160+
 161+ // Replace the &something_not_xml; with &amp;something_not_xml;
 162+ $replacement = '&amp;${1}';
 163+
 164+ return preg_replace( $pattern, $replacement, $text );
 165+ }
 166+ static function xml_attribute_entities( $text, $charset = 'Windows-1252' ) {
 167+ $ret = self::xml_entities( $text, $charset );
 168+ return str_replace( "\n", '&#10;', $ret );
 169+ }
111170 }
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_HTMLTag.php
@@ -27,17 +27,34 @@
2828 }
2929
3030 public function getAttributes() {
31 - return $this->m_attributes;
 31+ return $this->m_attrs;
3232 }
3333
 34+ public function getAttribute( $attr ) {
 35+ $attr = strtolower( $attr );
 36+ foreach ( $this->m_attrs as $a => $v ) {
 37+ $a = strtolower( $a );
 38+ $v = preg_replace( '/^[\'"](.*)[\'"]$/', '$1', $v );
 39+ if ( $attr == $a ) return $v;
 40+ }
 41+ }
 42+
3443 public function setAttributes( $attrs ) {
35 - $this->m_attributes = $attrs;
 44+ $this->m_attrs = $attrs;
3645 }
3746
3847 public function getWikiText() {
39 - return "<{$this->m_name}>" . parent::getWikiText() . "</{$this->m_name}>";
 48+ $attr = '';
 49+ foreach ( $this->m_attrs as $a => $v ) {
 50+ $attr .= " {$a}={$v}";
 51+ }
 52+ return "<{$this->m_name}{$attr}>" . parent::getWikiText() . "</{$this->m_name}>";
4053 }
4154
 55+ public function getInnerWikiText() {
 56+ return parent::getWikiText();
 57+ }
 58+
4259 public function updateOnNodeClosed() {
4360 // use SemanticForms to bind properties to fields
4461 }
@@ -52,6 +69,13 @@
5370 }
5471 }
5572 protected function getXMLAttributes() {
56 - return "name=\"{$this->m_name}\"";
 73+ $ret = 'name="' . self::xml_entities( $this->m_name ) . '"';
 74+ foreach ( $this->m_attrs as $a => $v ) {
 75+ $v = preg_replace( '/^"(.*)"$/', '$1', $v );
 76+ if ( $a == 'id' ) $a = 'tag_id';
 77+ $v = self::xml_entities( $v );
 78+ $ret .= " {$a}=\"{$v}\"";
 79+ }
 80+ return $ret;
5781 }
5882 }
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_ParserFunction.php
@@ -36,6 +36,6 @@
3737 }
3838
3939 protected function getXMLAttributes() {
40 - return "key=\"{$this->m_function_key}\"";
 40+ return 'key="' . self::xml_entities( $this->m_function_key ) . '"';
4141 }
4242 }
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Section.php
@@ -37,8 +37,8 @@
3838 }
3939
4040 public function getHeaderText() {
41 -// return "\n" .
42 - return substr( WOMSectionModel::$heading, 0, $this->m_level ) .
 41+ return ( $this->isLastLF() ? '' : "\n" ) .
 42+ substr( WOMSectionModel::$heading, 0, $this->m_level ) .
4343 $this->m_name .
4444 substr( WOMSectionModel::$heading, 0, $this->m_level ) .
4545 "\n";
@@ -69,6 +69,6 @@
7070 }
7171
7272 protected function getXMLAttributes() {
73 - return "name=\"{$this->m_name}\" level=\"{$this->m_level}\"";
 73+ return 'name="' . self::xml_entities( $this->m_name ) . '" level="' . $this->m_level . '"';
7474 }
7575 }
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Paragraph.php
@@ -0,0 +1,25 @@
 2+<?php
 3+/**
 4+ * This model implements Paragraph models.
 5+ *
 6+ * @author Ning
 7+ * @file
 8+ * @ingroup WikiObjectModels
 9+ *
 10+ */
 11+
 12+class WOMParagraphModel extends WikiObjectModelCollection {
 13+
 14+ public function __construct() {
 15+ parent::__construct( WOM_TYPE_PARAGRAPH );
 16+ }
 17+
 18+ public function getWikiText() {
 19+ $pre = $this->getPreviousObject();
 20+ return ( ( $pre != null && ( $pre->getTypeID() == WOM_TYPE_PARAGRAPH ) ) ? "\n\n" : '' ) . $this->getValueText();
 21+ }
 22+
 23+ public function getValueText() {
 24+ return parent::getWikiText();
 25+ }
 26+}
Index: trunk/extensions/WikiObjectModel/includes/models/WOM_OM_Template.php
@@ -57,6 +57,6 @@
5858 }
5959 }
6060 protected function getXMLAttributes() {
61 - return "name=\"{$this->m_name}\"";
 61+ return 'name="' . self::xml_entities( $this->m_name ) . '"';
6262 }
6363 }
Index: trunk/extensions/WikiObjectModel/includes/WOM_Processor.php
@@ -16,36 +16,36 @@
1717 private static $base_parser;
1818
1919 private static function setupParsers() {
20 - if ( WOMProcessor::$isParsersRegistered ) return;
 20+ if ( self::$isParsersRegistered ) return;
2121
2222 global $wgOMParsers;
2323 foreach ( $wgOMParsers as $p ) {
2424 $parser = new $p();
25 - WOMProcessor::$parsers[$parser->getParserID()] = $parser;
 25+ self::$parsers[$parser->getParserID()] = $parser;
2626 }
27 - WOMProcessor::$base_parser = WOMProcessor::$parsers[WOM_PARSER_ID_TEXT];
 27+ self::$base_parser = self::$parsers[WOM_PARSER_ID_TEXT];
2828
29 - WOMProcessor::$isParsersRegistered = true;
 29+ self::$isParsersRegistered = true;
3030 }
3131
3232 public static function getObjectParser( WikiObjectModel $obj ) {
3333 $fname = 'WikiObjectModel::getObjectParser (WOM)';
3434 wfProfileIn( $fname );
3535
36 - if ( !WOMProcessor::$isParsersRegistered ) {
37 - WOMProcessor::setupParsers();
 36+ if ( !self::$isParsersRegistered ) {
 37+ self::setupParsers();
3838 }
3939 global $wgOMModelParserMapping;
4040 if ( isset( $wgOMModelParserMapping[$obj->getTypeID()] ) ) {
4141 $id = $wgOMModelParserMapping[$obj->getTypeID()];
42 - if ( isset( WOMProcessor::$parsers[$id] ) ) {
 42+ if ( isset( self::$parsers[$id] ) ) {
4343 wfProfileOut( $fname );
44 - return WOMProcessor::$parsers[$id];
 44+ return self::$parsers[$id];
4545 }
4646 }
4747 wfProfileOut( $fname );
4848
49 - return WOMProcessor::$base_parser;
 49+ return self::$base_parser;
5050 }
5151
5252 private static function applyObjID( WikiObjectModel $wom, WOMPageModel $root ) {
@@ -53,7 +53,7 @@
5454 $root->addToPageObjectSet( $wom );
5555 if ( $wom instanceof WikiObjectModelCollection ) {
5656 foreach ( $wom->getObjects() as $obj ) {
57 - WOMProcessor::applyObjID( $obj, $root );
 57+ self::applyObjID( $obj, $root );
5858 }
5959 }
6060 }
@@ -62,23 +62,76 @@
6363 $fname = 'WikiObjectModel::parseToWOM (WOM)';
6464 wfProfileIn( $fname );
6565
66 - if ( !WOMProcessor::$isParsersRegistered ) {
67 - WOMProcessor::setupParsers();
 66+ if ( !self::$isParsersRegistered ) {
 67+ self::setupParsers();
6868 }
6969
7070 $root = new WOMPageModel();
71 - WOMProcessor::parseNext( $text, $root, $root );
72 - WOMProcessor::parseSentences( $root );
73 - WOMProcessor::applyObjID( $root, $root );
 71+ self::parseNext( $text, $root, $root );
 72+ self::parseParagraphs( $root );
 73+ self::parseSentences( $root );
 74+ self::applyObjID( $root, $root );
7475 wfProfileOut( $fname );
7576 return $root;
7677 }
7778
7879 /**
79 - * Special case, sentence is not standard wiki object
 80+ * Special case, paragraphs and sentences are not standard wiki object
8081 *
8182 * @param WOMPageModel $rootObj
8283 */
 84+ private static function parseParagraphs( WikiObjectModelCollection $wom ) {
 85+ global $wgOMParagraphObjectTypes;
 86+ $in_paragraph = false;
 87+ $new_objs = array();
 88+ $paragraphObj = null;
 89+ foreach ( $wom->getObjects() as $id => $obj ) {
 90+ if ( in_array( $obj->getTypeID(), $wgOMParagraphObjectTypes ) ) {
 91+ if ( !$in_paragraph ) {
 92+ $paragraphObj = new WOMParagraphModel();
 93+ $new_objs[] = $paragraphObj;
 94+ $in_paragraph = true;
 95+ }
 96+ $paragraphObj->insertObject( $obj );
 97+ // parse paragraph break
 98+ if ( $obj->getTypeID() == WOM_TYPE_TEXT ) {
 99+ $text = $obj->getWikiText();
 100+ $offset = 0;
 101+ $len = strlen( $text );
 102+ // HTML tag <p> is not valid 'paragraph' syntax in WOM
 103+ $r = preg_match_all( '/\n[ \t]*\n/', $text, $ms, PREG_SET_ORDER | PREG_OFFSET_CAPTURE );
 104+ if ( $r ) {
 105+ foreach ( $ms as $m ) {
 106+ $end = $m[0][1] + strlen( $m[0][0] );
 107+ $obj->setText( substr( $text, $offset, $m[0][1] - $offset ) );
 108+ $offset = $end;
 109+ $paragraphObj = new WOMParagraphModel();
 110+ $new_objs[] = $paragraphObj;
 111+ $obj = new WOMTextModel( substr( $text, $end ) );
 112+ $paragraphObj->insertObject( $obj );
 113+ }
 114+ }
 115+ }
 116+ } else {
 117+ $in_paragraph = false;
 118+ $paragraphObj = null;
 119+
 120+ if ( $obj->getTypeID() == WOM_TYPE_HTMLTAG ) {
 121+ // special case, html tag
 122+ } else if ( $obj instanceof WikiObjectModelCollection ) {
 123+ self::parseParagraphs( $obj );
 124+ }
 125+ $new_objs[] = $obj;
 126+ }
 127+ }
 128+
 129+ $wom->reset();
 130+
 131+ foreach ( $new_objs as $obj ) {
 132+ $wom->insertObject( $obj );
 133+ }
 134+ }
 135+
83136 private static function parseSentences( WikiObjectModelCollection $wom ) {
84137 global $wgOMSentenceObjectTypes;
85138 $in_sentence = false;
@@ -127,7 +180,7 @@
128181 if ( $obj->getTypeID() == WOM_TYPE_HTMLTAG ) {
129182 // special case, html tag
130183 } elseif ( $obj instanceof WikiObjectModelCollection ) {
131 - WOMProcessor::parseSentences( $obj );
 184+ self::parseSentences( $obj );
132185 }
133186 $new_objs[] = $obj;
134187 }
@@ -160,8 +213,8 @@
161214 $len = strlen( $text );
162215
163216 while ( $offset < $len ) {
164 - if ( WOMProcessor::getObjectParser( $parentObj ) != null ) {
165 - $objectClosed = WOMProcessor::getObjectParser( $parentObj )
 217+ if ( self::getObjectParser( $parentObj ) != null ) {
 218+ $objectClosed = self::getObjectParser( $parentObj )
166219 ->isObjectClosed( $parentObj, $text, $offset );
167220 if ( $objectClosed !== false ) {
168221 $offset += $objectClosed;
@@ -173,7 +226,7 @@
174227 $result = null;
175228 if ( $parserInstance == null ) {
176229 $parserInstance2 = null;
177 - foreach ( WOMProcessor::$parsers as $parser ) {
 230+ foreach ( self::$parsers as $parser ) {
178231 $parser_res = $parser->parseNext( $text, $parentObj, $offset );
179232 if ( $parser_res == null ) continue;
180233 if ( $parserInstance2 == null || $parser->subclassOf( $parserInstance2 ) ) {
@@ -182,7 +235,7 @@
183236 }
184237 }
185238 if ( $parserInstance2 == null ) {
186 - $parserInstance2 = WOMProcessor::$base_parser;
 239+ $parserInstance2 = self::$base_parser;
187240 $result = $parserInstance2->parseNext( $text, $parentObj, $offset );
188241 }
189242 } else {
@@ -208,27 +261,27 @@
209262 $next_obj->setParent( $parentObj );
210263 }
211264
212 - WOMProcessor::assemble( $next_obj );
 265+ self::assemble( $next_obj );
213266
214267 if ( $next_obj->isCollection() && !( isset( $result['closed'] ) && $result['closed'] ) ) {
215268 $collection_start = $offset;
216 - $d = WOMProcessor::parseNext( $text, $next_obj, $rootObj, $offset,
217 - ( ( $parserInstance2 != null && isset( WOMProcessor::$parsers[$parserInstance2->getSubParserID()] ) ) ?
218 - WOMProcessor::$parsers[$parserInstance2->getSubParserID()] :
 269+ $d = self::parseNext( $text, $next_obj, $rootObj, $offset,
 270+ ( ( $parserInstance2 != null && isset( self::$parsers[$parserInstance2->getSubParserID()] ) ) ?
 271+ self::$parsers[$parserInstance2->getSubParserID()] :
219272 null ) );
220273 if ( $d == 100 && $parserInstance2->isObjectClosed( $next_obj, $text, $offset ) === false ) {
221274 // rollback
222 - $p = WOMProcessor::getObjectParser( $parentObj );
 275+ $p = self::getObjectParser( $parentObj );
223276 if ( $p != null && $p->isObjectClosed( $parentObj, $text, $offset ) === false ) {
224277 return $d;
225278 }
226279 $parentObj->rollback();
227280 $offset = $collection_start - $result['len'];
228 - $result = WOMProcessor::$base_parser->parseNext( $text, $parentObj, $offset );
 281+ $result = self::$base_parser->parseNext( $text, $parentObj, $offset );
229282 $offset += $result['len'];
230283 $next_obj = $result['obj'];
231284 $next_obj->setParent( $parentObj );
232 - WOMProcessor::assemble( $next_obj );
 285+ self::assemble( $next_obj );
233286 } else {
234287 $next_obj->updateOnNodeClosed();
235288 }
@@ -281,9 +334,9 @@
282335 $possible_values[] = html_entity_decode( $value->getWikiValue() );
283336 }
284337 if ( count( $possible_values ) > 0 ) {
285 - $result = WOMProcessor::getSemanticEditor( 'enumeration' );
 338+ $result = self::getSemanticEditor( 'enumeration' );
286339 } else {
287 - $result = WOMProcessor::getSemanticEditor( $property->getPropertyTypeID() );
 340+ $result = self::getSemanticEditor( $property->getPropertyTypeID() );
288341 }
289342
290343 wfProfileOut( $fname );
@@ -332,7 +385,7 @@
333386 }
334387 $content = $revision->getText();
335388
336 - $wom = WOMProcessor::parseToWOM( $content );
 389+ $wom = self::parseToWOM( $content );
337390 $wom->setTitle( $title );
338391 $wom->setRevisionID( $revision->getId() );
339392
@@ -341,12 +394,22 @@
342395 return $wom;
343396 }
344397
345 - public static function getObjIdByXPath( $title, $xpath, $rid = 0 ) {
 398+ public static function getPageDom( $title, $rid = 0 ) {
346399 $fname = 'WikiObjectModel::getObjIdByXPath (WOM)';
347400 wfProfileIn( $fname );
348401
349 - $xml = WOMProcessor::getPageObject( $title, $rid )->toXML();
 402+ $xml = self::getPageObject( $title, $rid )->toXML();
350403 $xObj = simplexml_load_string( $xml );
 404+
 405+ wfProfileOut( $fname );
 406+ return $xObj;
 407+ }
 408+ public static function getObjIdByXPath2( WOMPageModel $wom_obj, $xpath ) {
 409+ $fname = 'WikiObjectModel::getObjIdByXPath2 (WOM)';
 410+ wfProfileIn( $fname );
 411+
 412+ $xml = $wom_obj->toXML();
 413+ $xObj = simplexml_load_string( $xml );
351414 try {
352415 $objs = $xObj->xpath( $xpath );
353416 } catch ( Exception $e ) {
@@ -364,12 +427,21 @@
365428 wfProfileOut( $fname );
366429 return $ret;
367430 }
 431+ public static function getObjIdByXPath( $title, $xpath, $rid = 0 ) {
 432+ $fname = 'WikiObjectModel::getObjIdByXPath (WOM)';
 433+ wfProfileIn( $fname );
368434
 435+ $ret = self::getObjIdByXPath2( self::getPageObject( $title, $rid ), $xpath );
 436+
 437+ wfProfileOut( $fname );
 438+ return $ret;
 439+ }
 440+
369441 public static function getSubObjectsByParentId( $title, $obj_id, $rid = 0 ) {
370442 $fname = 'WikiObjectModel::getSubPageObjectsByParentId (WOM)';
371443 wfProfileIn( $fname );
372444
373 - $wom = WOMProcessor::getPageObject( $title, $rid );
 445+ $wom = self::getPageObject( $title, $rid );
374446
375447 $obj = $wom->getObject( $obj_id );
376448
@@ -384,7 +456,7 @@
385457 $fname = 'WikiObjectModel::getPageObjectsByTypeID (WOM)';
386458 wfProfileIn( $fname );
387459
388 - $wom = WOMProcessor::getPageObject( $title, $rid );
 460+ $wom = self::getPageObject( $title, $rid );
389461
390462 $result = $wom->getObjectsByTypeID( $type_id );
391463
@@ -397,7 +469,7 @@
398470 $fname = 'WikiObjectModel::getPageTemplates (WOM)';
399471 wfProfileIn( $fname );
400472
401 - $result = WOMProcessor::getPageObjectsByTypeID(
 473+ $result = self::getPageObjectsByTypeID(
402474 WOM_TYPE_TEMPLATE, $title, $rid );
403475
404476 if ( $name == '' ) {
@@ -420,7 +492,7 @@
421493 $fname = 'WikiObjectModel::getPageCategories (WOM)';
422494 wfProfileIn( $fname );
423495
424 - $result = WOMProcessor::getPageObjectsByTypeID(
 496+ $result = self::getPageObjectsByTypeID(
425497 WOM_TYPE_CATEGORY, $title, $rid );
426498
427499 wfProfileOut( $fname );
@@ -432,7 +504,7 @@
433505 $fname = 'WikiObjectModel::getPageLinks (WOM)';
434506 wfProfileIn( $fname );
435507
436 - $result = WOMProcessor::getPageObjectsByTypeID(
 508+ $result = self::getPageObjectsByTypeID(
437509 WOM_TYPE_LINK, $title, $rid );
438510
439511 wfProfileOut( $fname );
@@ -445,7 +517,7 @@
446518 wfProfileIn( $fname );
447519
448520 // do not return properties which are binding template fields, in current version
449 - $result = WOMProcessor::getPageObjectsByTypeID(
 521+ $result = self::getPageObjectsByTypeID(
450522 WOM_TYPE_PROPERTY, $title, $rid );
451523
452524 wfProfileOut( $fname );
@@ -457,7 +529,7 @@
458530 $fname = 'WikiObjectModel::getParserFunctions (WOM)';
459531 wfProfileIn( $fname );
460532
461 - $result = WOMProcessor::getPageObjectsByTypeID(
 533+ $result = self::getPageObjectsByTypeID(
462534 WOM_TYPE_PARSERFUNCTION, $title, $rid );
463535
464536 if ( $function_key == '' ) {
@@ -489,7 +561,7 @@
490562 return;
491563 }
492564 }
493 - $wom = WOMProcessor::getPageObject( $title, $revision_id );
 565+ $wom = self::getPageObject( $title, $revision_id );
494566 $wom->insertPageObject( $object, $obj_id );
495567
496568 // save to wiki
@@ -513,7 +585,7 @@
514586 return;
515587 }
516588 }
517 - $wom = WOMProcessor::getPageObject( $title, $revision_id );
 589+ $wom = self::getPageObject( $title, $revision_id );
518590 $parent = $wom->getObject( $obj_id );
519591 if ( !( $parent instanceof WikiObjectModelCollection ) ) {
520592 throw new MWException( __METHOD__ . ": Object is not a collection object '{$title} ({$revision_id}) - {$obj_id}'" );
@@ -543,7 +615,7 @@
544616 return;
545617 }
546618 }
547 - $wom = WOMProcessor::getPageObject( $title, $revision_id );
 619+ $wom = self::getPageObject( $title, $revision_id );
548620 $wom->updatePageObject( $object, $obj_id );
549621
550622 // save to wiki
@@ -567,7 +639,7 @@
568640 return;
569641 }
570642 }
571 - $wom = WOMProcessor::getPageObject( $title, $revision_id );
 643+ $wom = self::getPageObject( $title, $revision_id );
572644 $wom->removePageObject( $obj_id );
573645
574646 // save to wiki
@@ -591,8 +663,8 @@
592664 return;
593665 }
594666 }
595 - $wom = WOMProcessor::getPageObject( $title, $revision_id );
596 - $text = WOMProcessor::getValidText( $text, $wom->getObject( $obj_id )->getParent(), $wom );
 667+ $wom = self::getPageObject( $title, $revision_id );
 668+ $text = self::getValidText( $text, $wom->getObject( $obj_id )->getParent(), $wom );
597669 // no need to parse or merge object model but use text
598670 $wom->insertPageObject( new WOMTextModel( $text ), $obj_id );
599671
@@ -617,14 +689,14 @@
618690 return;
619691 }
620692 }
621 - $wom = WOMProcessor::getPageObject( $title, $revision_id );
 693+ $wom = self::getPageObject( $title, $revision_id );
622694 $parent = $wom->getObject( $obj_id );
623695 if ( !( $parent instanceof WikiObjectModelCollection ) ) {
624696 throw new MWException( __METHOD__ . ": Object is not a collection object '{$title} ({$revision_id}) - {$obj_id}'" );
625697 wfProfileOut( $fname );
626698 return;
627699 }
628 - $text = WOMProcessor::getValidText( $text, $parent, $wom );
 700+ $text = self::getValidText( $text, $parent, $wom );
629701 // no need to parse or merge object model but use text
630702 $wom->appendChildObject( new WOMTextModel( $text ), $obj_id );
631703
@@ -649,8 +721,8 @@
650722 return;
651723 }
652724 }
653 - $wom = WOMProcessor::getPageObject( $title, $revision_id );
654 - $text = WOMProcessor::getValidText( $text, $wom->getObject( $obj_id )->getParent(), $wom );
 725+ $wom = self::getPageObject( $title, $revision_id );
 726+ $text = self::getValidText( $text, $wom->getObject( $obj_id )->getParent(), $wom );
655727 // no need to parse or merge object model but use text
656728 $wom->updatePageObject( new WOMTextModel( $text ), $obj_id );
657729
@@ -664,13 +736,13 @@
665737
666738 private static function getValidText( $text, $parent, $wom ) {
667739 if ( $parent != null ) {
668 - $parserId = WOMProcessor::getObjectParser( $parent )->getSubParserID();
 740+ $parserId = self::getObjectParser( $parent )->getSubParserID();
669741 if ( $parserId != '' ) {
670 - $parser = WOMProcessor::$parsers[$parserId];
 742+ $parser = self::$parsers[$parserId];
671743 $offset = 0;
672744 $p2 = clone ( $parent );
673745 $p2->reset();
674 - WOMProcessor::parseNext( $text, $p2, $wom, $offset, $parser );
 746+ self::parseNext( $text, $p2, $wom, $offset, $parser );
675747 $text = '';
676748 foreach ( $p2->getObjects() as $obj ) {
677749 $text .= $obj->getWikiText();
@@ -684,10 +756,10 @@
685757 $fname = 'WikiObjectModel::getToc (WOM)';
686758 wfProfileIn( $fname );
687759
688 - $wom = WOMProcessor::getPageObject( $title, $revision_id );
 760+ $wom = self::getPageObject( $title, $revision_id );
689761
690762 $arr = array();
691 - WOMProcessor::saveToToc( $wom, $arr );
 763+ self::saveToToc( $wom, $arr );
692764
693765 wfProfileOut( $fname );
694766
@@ -698,7 +770,7 @@
699771 foreach ( $wom->getObjects() as $obj ) {
700772 if ( $obj->getTypeID() == WOM_TYPE_SECTION ) {
701773 $sec = array( 'section' => $obj->getName(), 'sub' => array() );
702 - WOMProcessor::saveToToc( $obj, $sec['sub'] );
 774+ self::saveToToc( $obj, $sec['sub'] );
703775 $arr[] = $sec;
704776 }
705777 }
@@ -726,7 +798,7 @@
727799 $fname = 'WikiObjectModel::objectToWikiText (WOM)';
728800 wfProfileIn( $fname );
729801
730 - $wom = WOMProcessor::getPageObject( $title, $revision_id );
 802+ $wom = self::getPageObject( $title, $revision_id );
731803
732804 $obj = $wom->getObject( $obj_id );
733805
Index: trunk/extensions/WikiObjectModel/includes/WOM_Setup.php
@@ -21,11 +21,13 @@
2222 $wgAutoloadClasses['WOMLinkModel'] = $wgOMIP . '/includes/models/WOM_OM_Link.php';
2323 $wgAutoloadClasses['WOMSectionModel'] = $wgOMIP . '/includes/models/WOM_OM_Section.php';
2424 $wgAutoloadClasses['WOMSentenceModel'] = $wgOMIP . '/includes/models/WOM_OM_Sentence.php';
 25+$wgAutoloadClasses['WOMParagraphModel'] = $wgOMIP . '/includes/models/WOM_OM_Paragraph.php';
2526 $wgAutoloadClasses['WOMListItemModel'] = $wgOMIP . '/includes/models/WOM_OM_ListItem.php';
2627 $wgAutoloadClasses['WOMTableModel'] = $wgOMIP . '/includes/models/WOM_OM_Table.php';
2728 $wgAutoloadClasses['WOMTableCellModel'] = $wgOMIP . '/includes/models/WOM_OM_TblCell.php';
2829 $wgAutoloadClasses['WOMMagicWordModel'] = $wgOMIP . '/includes/models/WOM_OM_MagicWord.php';
2930 $wgAutoloadClasses['WOMHTMLTagModel'] = $wgOMIP . '/includes/models/WOM_OM_HTMLTag.php';
 31+$wgAutoloadClasses['WOMTemplateFieldHolderModel'] = $wgOMIP . '/includes/models/WOM_OM_TmplFieldHolder.php';
3032
3133 // Definitions
3234 define( 'WOM_TYPE_PAGE' , 'page' );
@@ -40,11 +42,13 @@
4143 define( 'WOM_TYPE_PARAM_VALUE' , 'value' );
4244 define( 'WOM_TYPE_TMPL_FIELD' , 'template_field' );
4345 define( 'WOM_TYPE_SENTENCE' , 'sentence' );
 46+define( 'WOM_TYPE_PARAGRAPH' , 'paragraph' );
4447 define( 'WOM_TYPE_LISTITEM' , 'list_item' );
4548 define( 'WOM_TYPE_TABLE' , 'table' );
4649 define( 'WOM_TYPE_TBL_CELL' , 'table_cell' );
4750 define( 'WOM_TYPE_MAGICWORD' , 'magicword' );
4851 define( 'WOM_TYPE_HTMLTAG' , 'html' );
 52+define( 'WOM_TYPE_TMPL_FIELD_HOLDER', 'template_field_holder' );
4953
5054 // POM Parser
5155 $wgAutoloadClasses['WikiObjectModelParser'] = $wgOMIP . '/includes/parsers/WikiObjectModelParser.php';
@@ -62,6 +66,7 @@
6367 $wgAutoloadClasses['WOMTableCellParser'] = $wgOMIP . '/includes/parsers/WOMTblCellParser.php';
6468 $wgAutoloadClasses['WOMMagicWordParser'] = $wgOMIP . '/includes/parsers/WOMMagicWordParser.php';
6569 $wgAutoloadClasses['WOMHTMLTagParser'] = $wgOMIP . '/includes/parsers/WOMHTMLTagParser.php';
 70+$wgAutoloadClasses['WOMTemplateFieldHolderParser'] = $wgOMIP . '/includes/parsers/WOMTemplateFieldHolderParser.php';
6671
6772 // Definitions
6873 define( 'WOM_PARSER_ID_CATEGORY' , 'category' );
@@ -78,6 +83,7 @@
7984 define( 'WOM_PARSER_ID_TABLECELL' , 'tbl_cell' );
8085 define( 'WOM_PARSER_ID_MAGICWORD' , 'magicword' );
8186 define( 'WOM_PARSER_ID_HTMLTAG' , 'html' );
 87+define( 'WOM_PARSER_ID_TEMPLATE_FIELD_HOLDER', 'template_field_holder' );
8288
8389 global $wgOMParsers, $wgOMModelParserMapping;
8490 $wgOMParsers = array(
@@ -95,6 +101,7 @@
96102 'WOMTableCellParser',
97103 'WOMMagicWordParser',
98104 'WOMHTMLTagParser',
 105+ 'WOMTemplateFieldHolderParser',
99106 );
100107
101108 $wgOMModelParserMapping = array(
@@ -113,6 +120,7 @@
114121 WOM_TYPE_TBL_CELL => WOM_PARSER_ID_TABLECELL,
115122 WOM_TYPE_MAGICWORD => WOM_PARSER_ID_MAGICWORD,
116123 WOM_TYPE_HTMLTAG => WOM_PARSER_ID_HTMLTAG,
 124+ WOM_TYPE_TMPL_FIELD_HOLDER => WOM_PARSER_ID_TEMPLATE_FIELD_HOLDER,
117125 );
118126
119127 global $wgOMSentenceObjectTypes;
@@ -122,13 +130,23 @@
123131 WOM_TYPE_LINK,
124132 WOM_TYPE_CATEGORY,
125133 WOM_TYPE_MAGICWORD,
 134+ WOM_TYPE_TMPL_FIELD_HOLDER,
126135 );
127136
 137+global $wgOMParagraphObjectTypes;
 138+$wgOMParagraphObjectTypes = $wgOMSentenceObjectTypes;
 139+$wgOMParagraphObjectTypes[] = WOM_TYPE_LISTITEM;
 140+$wgOMParagraphObjectTypes[] = WOM_TYPE_PARSERFUNCTION;
 141+$wgOMParagraphObjectTypes[] = WOM_TYPE_TEMPLATE;
 142+
128143 // APIs
129144 global $wgAPIModules;
130145 $wgAPIModules['womset'] = 'ApiWOMSetObjectModel';
131146 $wgAutoloadClasses['ApiWOMSetObjectModel'] = $wgOMIP . '/includes/apis/WOM_SetObjectModel.php';
132147 $wgAPIModules['womget'] = 'ApiWOMGetObjectModel';
133148 $wgAutoloadClasses['ApiWOMGetObjectModel'] = $wgOMIP . '/includes/apis/WOM_GetObjectModel.php';
 149+$wgAPIModules['womquery'] = 'ApiWOMQuery';
 150+$wgAutoloadClasses['ApiWOMQuery'] = $wgOMIP . '/includes/apis/WOM_Query.php';
 151+$wgAPIModules['womoutput'] = 'ApiWOMOutputObjectModel';
 152+$wgAutoloadClasses['ApiWOMOutputObjectModel'] = $wgOMIP . '/includes/apis/WOM_OutputObjectModel.php';
134153
135 -
Index: trunk/extensions/WikiObjectModel/includes/apis/WOM_OutputObjectModel.php
@@ -0,0 +1,139 @@
 2+<?php
 3+
 4+global $wgOMIP;
 5+require_once( $wgOMIP . '/includes/apis/WOM_OutputProcessor.php' );
 6+
 7+/**
 8+ * @addtogroup API
 9+ */
 10+class ApiWOMOutputObjectModel extends ApiBase {
 11+
 12+ public function __construct( $main, $action ) {
 13+ parent :: __construct( $main, $action );
 14+ }
 15+
 16+ public function execute() {
 17+ global $wgUser;
 18+
 19+ $params = $this->extractRequestParams();
 20+ if ( is_null( $params['page'] ) )
 21+ $this->dieUsage( 'Must specify page title', 0 );
 22+ if ( is_null( $params['xpath'] ) )
 23+ $this->dieUsage( 'Must specify xpath', 1 );
 24+
 25+ $page = $params['page'];
 26+ $xpath = $params['xpath'];
 27+ $type = $params['type'];
 28+ $rid = $params['rid'];
 29+
 30+
 31+ $articleTitle = Title::newFromText( $page );
 32+ if ( !$articleTitle )
 33+ $this->dieUsage( "Can't create title object ($page)", 2 );
 34+
 35+ $article = new Article( $articleTitle );
 36+ if ( !$article->exists() )
 37+ $this->dieUsage( "Article doesn't exist ($page)", 3 );
 38+
 39+ $page_obj = WOMOutputProcessor::getOutputData( $articleTitle, $rid );
 40+ try {
 41+ $objs = WOMProcessor::getObjIdByXPath2( $page_obj, $xpath );
 42+ } catch ( Exception $e ) {
 43+ $err = $e->getMessage();
 44+ }
 45+
 46+ $result = array();
 47+
 48+ if ( isset( $err ) ) {
 49+ $result = array(
 50+ 'result' => 'Failure',
 51+ 'message' => array(),
 52+ );
 53+ $this->getResult()->setContent( $result['message'], $err );
 54+ } else {
 55+ $result['result'] = 'Success';
 56+
 57+ // pay attention to special xml tag, e.g., <property><value>...</value></property>
 58+ $result['return'] = array();
 59+ if ( $type == 'count' ) {
 60+ $count = 0;
 61+ foreach ( $objs as $id ) {
 62+ if ( $id == '' ) continue;
 63+ ++ $count;
 64+ }
 65+ $this->getResult()->setContent( $result['return'], $count );
 66+ } else {
 67+ $xml = '';
 68+ foreach ( $objs as $id ) {
 69+ if ( $id == '' ) continue;
 70+ $wobj = $page_obj->getObject( $id );
 71+ $result['return'][$id] = array();
 72+ if ( $type == 'xml' ) {
 73+ $xml .= "<{$id} xml:space=\"preserve\">{$wobj->toXML()}</{$id}>";
 74+ } else {
 75+ $this->getResult()->setContent( $result['return'][$id], $wobj->getWikiText() );
 76+ }
 77+ }
 78+ if ( $type == 'xml' ) {
 79+ header ( "Content-Type: application/rdf+xml" );
 80+ echo <<<OUTPUT
 81+<?xml version="1.0" encoding="UTF-8" ?>
 82+<api><womget result="Success"><return>
 83+{$xml}
 84+</return></womget></api>
 85+OUTPUT;
 86+ exit( 1 );
 87+ }
 88+ }
 89+ }
 90+ $this->getResult()->addValue( null, $this->getModuleName(), $result );
 91+ }
 92+
 93+ protected function getAllowedParams() {
 94+ return array (
 95+ 'page' => null,
 96+ 'xpath' => null,
 97+ 'type' => array(
 98+ ApiBase :: PARAM_DFLT => 'wiki',
 99+ ApiBase :: PARAM_TYPE => array(
 100+ 'wiki',
 101+ 'count',
 102+ 'xml',
 103+ ),
 104+ ),
 105+ 'rid' => array (
 106+ ApiBase :: PARAM_TYPE => 'integer',
 107+ ApiBase :: PARAM_DFLT => 0,
 108+ ApiBase :: PARAM_MIN => 0
 109+ ),
 110+ );
 111+ }
 112+
 113+ protected function getParamDescription() {
 114+ return array (
 115+ 'page' => 'Title of the page to modify',
 116+ 'xpath' => 'DOM-like xpath to locate WOM object instances (http://www.w3schools.com/xpath/xpath_syntax.asp)',
 117+ 'type' => array (
 118+ 'Type to fetch useful wiki object data',
 119+ 'type = wiki, get wiki text of specified object',
 120+ 'type = count, get objects count with specified xpath',
 121+ 'type = xml, view "encoded objects\' xml" with specified xpath, usually use with format=xml',
 122+ ),
 123+ 'rid' => 'Revision id of specified page - by dafault latest updated revision (0) is used',
 124+ );
 125+ }
 126+
 127+ protected function getDescription() {
 128+ return 'Call to get object values to Wiki Object Model';
 129+ }
 130+
 131+ protected function getExamples() {
 132+ return array (
 133+ 'api.php?action=womget&page=Somepage&xpath=//template[@name=SomeTempate]/template_field[@key=templateparam]'
 134+ );
 135+ }
 136+
 137+ public function getVersion() {
 138+ return __CLASS__ . ': $Id$';
 139+ }
 140+}
Index: trunk/extensions/WikiObjectModel/includes/apis/WOM_OM_QueryResult.php
@@ -0,0 +1,16 @@
 2+<?php
 3+/**
 4+ * This model implements Query result models.
 5+ *
 6+ * @author Ning
 7+ * @file
 8+ * @ingroup WikiObjectModels
 9+ *
 10+ */
 11+
 12+class WOMQueryResult extends WikiObjectModelCollection {
 13+
 14+ public function __construct() {
 15+ parent::__construct( 'q_result' );
 16+ }
 17+}
Index: trunk/extensions/WikiObjectModel/includes/apis/WOM_OutputProcessor.php
@@ -0,0 +1,296 @@
 2+<?php
 3+if ( !defined( 'MEDIAWIKI' ) ) die;
 4+
 5+global $wgHooks, $wgParser;
 6+if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
 7+ $wgHooks['ParserFirstCallInit'][] = 'WOMOutputProcessor::smwgWTregisterParserFunctions';
 8+} else {
 9+ if ( class_exists( 'StubObject' ) && !StubObject::isRealObject( $wgParser ) ) {
 10+ $wgParser->_unstub();
 11+ }
 12+ WOMOutputProcessor::smwgWTregisterParserFunctions( $wgParser );
 13+}
 14+
 15+global $wgOMOutputHookedParserFunctions;
 16+$wgOMOutputHookedParserFunctions = array(
 17+ 'ask',
 18+ 'sparql',
 19+);
 20+
 21+global $wgOMIP;
 22+require_once( $wgOMIP . '/includes/apis/WOM_OM_QueryResult.php' );
 23+
 24+class WOMOutputProcessor {
 25+ static function smwfProcessSPARQLQueryParserFunctionGTP( &$parser ) {
 26+ global $smwgWebserviceEndpoint;
 27+ if ( !isset( $smwgWebserviceEndpoint ) ) return '';
 28+
 29+ global $smwgIQRunningNumber;
 30+ $smwgIQRunningNumber++;
 31+ $params = func_get_args();
 32+ array_shift( $params ); // we already know the $parser ...
 33+
 34+ SMWSPARQLQueryProcessor::processFunctionParams( $params, $querystring, $params, $printouts );
 35+ $query = SMWSPARQLQueryProcessor::createQuery( $querystring, $params, SMWQueryProcessor::INLINE_QUERY, '', $printouts );
 36+
 37+ if ( !( ( $query->querymode == SMWQuery::MODE_INSTANCES ) || ( $query->querymode == SMWQuery::MODE_NONE ) ) ) {
 38+ return '';
 39+ }
 40+ self::prequery( $params, $printouts, $label, $wom_id );
 41+
 42+ // source from SMWHalo, SMW_SPARQLQueryProcessor.php
 43+
 44+ // Query routing allows extensions to provide alternative stores as data sources
 45+ // The while feature is experimental and is not properly integrated with most of SMW's architecture. For instance, some query printers just fetch their own store.
 46+ /// TODO: case-insensitive
 47+ global $smwgQuerySources;
 48+
 49+ $query->params = $params; // this is a hack
 50+
 51+ if ( array_key_exists( "source", $params ) && array_key_exists( $params["source"], $smwgQuerySources ) ) {
 52+ $store = new $smwgQuerySources[$params["source"]]();
 53+ } else {
 54+ $store = smwfGetStore(); // default store
 55+ }
 56+
 57+ $res = $store->getQueryResult( $query );
 58+
 59+ if ( !is_array( $res ) ) {
 60+ $qResults['tsc'] = $res;
 61+ } else {
 62+ $qResults = $res;
 63+ }
 64+
 65+ foreach ( $qResults as $source => $res ) {
 66+ while ( $row = $res->getNext() ) {
 67+ $firstcol = true;
 68+ foreach ( $row as $field ) {
 69+ $object = $field->getNextObject();
 70+ $text = $object->getWikiValue();
 71+ self::$queryProps[$wom_id][$label][] = $text;
 72+
 73+ // get the first column only
 74+ break;
 75+ }
 76+ }
 77+ }
 78+
 79+ return '';
 80+ }
 81+ private static function prequery( &$params, $printouts, &$label, &$wom_id ) {
 82+ if ( isset( $params['mainlabel'] ) ) {
 83+ $label = $params['mainlabel'];
 84+ if ( $label == '-' ) {
 85+ $pr = $printouts[0];
 86+ $label = $pr->getLabel();
 87+ }
 88+ } else {
 89+ $label = '{Query #' . self::$queryId . '}';
 90+ self::$queryId ++;
 91+ }
 92+
 93+ if ( !isset( $params['limit'] ) ) {
 94+ $params['limit'] = 20; // limit to 20 result by default
 95+ }
 96+ $wom_id = '';
 97+ if ( isset( $params['wom_id'] ) ) {
 98+ $wom_id = $params['wom_id'];
 99+ }
 100+ }
 101+ static function smwfProcessInlineQueryParserFunctionGTP( &$parser ) {
 102+ global $smwgQEnabled, $smwgIQRunningNumber;
 103+ if ( $smwgQEnabled ) {
 104+ $smwgIQRunningNumber++;
 105+ $rawparams = func_get_args();
 106+ array_shift( $rawparams ); // we already know the $parser ...
 107+
 108+ SMWQueryProcessor::processFunctionParams( $rawparams, &$querystring, &$params, &$printouts );
 109+ self::prequery( $params, $printouts, $label, $wom_id );
 110+
 111+ $query = SMWQueryProcessor::createQuery(
 112+ $querystring,
 113+ $params,
 114+ SMWQueryProcessor::INLINE_QUERY,
 115+ SMW_OUTPUT_WIKI,
 116+ $printouts
 117+ );
 118+ $res = smwfGetStore()->getQueryResult( $query );
 119+
 120+ while ( $row = $res->getNext() ) {
 121+ $firstcol = true;
 122+ foreach ( $row as $field ) {
 123+ $object = $field->getNextObject();
 124+ $text = $object->getWikiValue();
 125+ self::$queryProps[$wom_id][$label][] = $text;
 126+
 127+ // get the first column only
 128+ break;
 129+ }
 130+ }
 131+ }
 132+ return '';
 133+ }
 134+
 135+ static function smwgWTregisterParserFunctions( &$parser ) {
 136+ global $wgWOMOutputHooked;
 137+ if ( $wgWOMOutputHooked === true ) {
 138+ if ( defined( SMW_VERSION ) ) {
 139+ $parser->setFunctionHook( 'ask', 'WOMOutputProcessor::smwfProcessInlineQueryParserFunctionGTP' );
 140+ }
 141+ if ( defined( SMW_HALO_VERSION ) ) {
 142+ $parser->setFunctionHook( 'sparql', 'WOMOutputProcessor::smwfProcessSPARQLQueryParserFunctionGTP' );
 143+ }
 144+ }
 145+ return true; // always return true, in order not to stop MW's hook processing!
 146+ }
 147+
 148+ private static function removeSubWOMIds( WikiObjectModelCollection $parent ) {
 149+ foreach ( $parent->getObjects() as $wobj ) {
 150+ $wobj->setObjectID( '' );
 151+ if ( $wobj instanceof WikiObjectModelCollection ) {
 152+ self::removeSubWOMIds( $wobj );
 153+ }
 154+ }
 155+ }
 156+
 157+ static $queryProps = null;
 158+ static $queryId = 0;
 159+ static function getOutputData( $title, $rid = 0 ) {
 160+ // normal page
 161+ global $wgTitle, $wgUser;
 162+ $wgTitle = $title;
 163+ $revision = Revision::newFromTitle( $title, $rid );
 164+ if ( $revision === NULL ) {
 165+ throw new MWException( __METHOD__ . ": Page not exist '{$page_name} ({$rid})'" );
 166+ }
 167+ $text = $revision->getText();
 168+ $wom = WOMProcessor::parseToWOM( $text );
 169+
 170+ global $wgOMOutputHookedParserFunctions;
 171+ $pfs = $wom->getObjectsByTypeID( WOM_TYPE_PARSERFUNCTION );
 172+ foreach ( $pfs as $id => $obj ) {
 173+ self::removeSubWOMIds( $obj );
 174+ foreach ( $wgOMOutputHookedParserFunctions as $function_key ) {
 175+ if ( $obj->getFunctionKey() == $function_key ) {
 176+ // add wom id to parser function, with specified parameter 'wom_id'
 177+ $param = new WOMParameterModel( 'wom_id' );
 178+ $pv = new WOMParamValueModel();
 179+ $param->insertObject( $pv );
 180+ $pv->insertObject( new WOMTextModel( $id ) );
 181+ $obj->insertObject( $param );
 182+ }
 183+ }
 184+ }
 185+ // FIXME: template values may have object ids
 186+ $tmpls = $wom->getObjectsByTypeID( WOM_TYPE_TEMPLATE );
 187+ foreach ( $tmpls as $id => $obj ) {
 188+ self::removeSubWOMIds( $obj );
 189+ }
 190+
 191+ global $wgParser, $wgOut, $wgWOMOutputHooked;
 192+ $wgWOMOutputHooked = true;
 193+ $options = ParserOptions::newFromUser( $wgUser );
 194+
 195+ self::$queryProps = array();
 196+ self::$queryId = 1;
 197+ $wgParser->parse( $wom->getWikiText(), $title, $options );
 198+
 199+ $output = SMWParseData::getSMWdata( $wgParser );
 200+
 201+ if ( !isset( $output ) ) {
 202+ $semdata = smwfGetStore()->getSemanticData( $title );
 203+ } else {
 204+ $semdata = $output;
 205+ }
 206+
 207+ $tmp_id = 0;
 208+ // fill in semantic properties
 209+ $properties = array();
 210+ foreach ( $semdata->getProperties() as $property ) {
 211+ if ( !$property->isShown() ) { // showing this is not desired, hide
 212+ continue;
 213+ } elseif ( $property->isUserDefined() ) { // user defined property
 214+ $property->setCaption( preg_replace( '/[ ]/u', '&nbsp;', $property->getWikiValue(), 2 ) );
 215+ // / NOTE: the preg_replace is a slight hack to ensure that the left column does not get too narrow
 216+ $properties[$property->getWikiValue()] = array();
 217+ } elseif ( $property->isVisible() ) { // predefined property
 218+ $properties[$property->getWikiValue()] = array();
 219+ } else { // predefined, internal property
 220+ continue;
 221+ }
 222+
 223+ $propvalues = $semdata->getPropertyValues( $property );
 224+ foreach ( $propvalues as $propvalue ) {
 225+ $properties[$property->getWikiValue()][$propvalue->getWikiValue()] = false;
 226+ }
 227+ }
 228+ $props = $wom->getObjectsByTypeID( WOM_TYPE_PROPERTY );
 229+ foreach ( $props as $prop ) {
 230+ $id = $prop->getObjectID();
 231+ if ( $id == '' ) continue;
 232+ $name = $prop->getPropertyName();
 233+ $value = $prop->getPropertyValue();
 234+ if ( !isset( $properties[$name][$value] ) ) {
 235+ // remove category not match to output
 236+ $wom->removePageObject( $id );
 237+ } else {
 238+ $properties[$name][$value] = true;
 239+ }
 240+ }
 241+ foreach ( $properties as $name => $values ) {
 242+ foreach ( $values as $val => $flag ) {
 243+ if ( $flag !== true ) {
 244+ $p = new WOMPropertyModel( $name, $val );
 245+ $p->setObjectID( 'output' . ( $tmp_id ++ ) );
 246+ $wom->insertObject( $p );
 247+ $wom->addToPageObjectSet( $p );
 248+ }
 249+ }
 250+ }
 251+
 252+ // fill in ask query results
 253+ foreach ( self::$queryProps as $wom_id => $queries ) {
 254+ $query_res = new WOMQueryResult();
 255+ if ( $wom_id != '' ) {
 256+ $parent = $wom->getObject( $wom_id );
 257+ } else {
 258+ $parent = new WOMParserFunctionModel( 'ask' );
 259+ $parent->setObjectID( 'output' . ( $tmp_id ++ ) );
 260+ $wom->insertObject( $parent );
 261+ $wom->addToPageObjectSet( $parent );
 262+ }
 263+ $parent->insertObject( $query_res );
 264+ foreach ( $queries as $label => $vals ) {
 265+ $vals = array_unique( $vals );
 266+ foreach ( $vals as $val ) {
 267+ $query_res->insertObject( new WOMPropertyModel( $label, $val ) );
 268+ }
 269+ }
 270+ }
 271+
 272+ // fill in categories
 273+ $categories = $title->getParentCategories();
 274+ $cates = $wom->getObjectsByTypeID( WOM_TYPE_CATEGORY );
 275+ foreach ( $cates as $cate ) {
 276+ $id = $cate->getObjectID();
 277+ if ( $id == '' ) continue;
 278+ $name = Title::newFromText( $cate->getName(), NS_CATEGORY )->getFullText();
 279+ if ( !isset( $categories[$name] ) ) {
 280+ // remove category not match to output
 281+ $wom->removePageObject( $id );
 282+ } else {
 283+ $categories[$name] = true;
 284+ }
 285+ }
 286+ foreach ( $categories as $cate => $flag ) {
 287+ if ( $flag !== true ) {
 288+ $c = new WOMCategoryModel( Title::newFromText( $cate )->getText() );
 289+ $c->setObjectID( 'output' . ( $tmp_id ++ ) );
 290+ $wom->insertObject( $c );
 291+ $wom->addToPageObjectSet( $c );
 292+ }
 293+ }
 294+
 295+ return $wom;
 296+ }
 297+}
Index: trunk/extensions/WikiObjectModel/includes/apis/WOM_SetObjectModel.php
@@ -38,6 +38,15 @@
3939 if ( !$article->exists() )
4040 $this->dieUsage( "Article doesn't exist ($page)", 4 );
4141
 42+// $ep = new EditPage( $article );
 43+// // EditPage wants to parse its stuff from a WebRequest
 44+// // That interface kind of sucks, but it's workable
 45+// $reqArr = array( 'wpTextbox1' => $params['text'],
 46+// 'wpEditToken' => $params['token'],
 47+// 'wpIgnoreBlankSummary' => ''
 48+// );
 49+// if ( !is_null( $summary ) )
 50+// $reqArr['wpSummary'] = $summary;
4251
4352 try {
4453 $objs = WOMProcessor::getObjIdByXPath( $articleTitle, $xpath, $rid );
@@ -119,6 +128,7 @@
120129 protected function getAllowedParams() {
121130 return array (
122131 'page' => null,
 132+// 'token' => null,
123133 'verb' => array(
124134 ApiBase :: PARAM_DFLT => 'update',
125135 ApiBase :: PARAM_TYPE => array(
@@ -153,6 +163,7 @@
154164 protected function getParamDescription() {
155165 return array (
156166 'page' => 'Title of the page to modify',
 167+// 'token' => 'Edit token. You can get one of these through prop=info',
157168 'verb' => 'Action verb to set to change wiki object instances',
158169 'xpath' => array(
159170 'DOM-like xpath to locate WOM object instances (http://www.w3schools.com/xpath/xpath_syntax.asp)',
@@ -183,7 +194,7 @@
184195
185196 protected function getExamples() {
186197 return array (
187 - 'api.php?action=womset&page=Somepage&xpath=//template[@name=SomeTempate]/template_field[@key=templateparam]&value=It+works!&summary=Editing+template+param+using+Wiki+Object+Model'
 198+ 'api.php?action=womset&page=Somepage&token=ABC123&xpath=//template[@name=SomeTempate]/template_field[@key=templateparam]&value=It+works!&summary=Editing+template+param+using+Wiki+Object+Model'
188199 );
189200 }
190201
Index: trunk/extensions/WikiObjectModel/includes/apis/WOM_Query.php
@@ -0,0 +1,154 @@
 2+<?php
 3+
 4+/**
 5+ * @addtogroup API
 6+ */
 7+class ApiWOMQuery extends ApiBase {
 8+
 9+ public function __construct( $main, $action ) {
 10+ parent :: __construct( $main, $action );
 11+ }
 12+
 13+ // given the 'key', return the result set of 'xpath' or wiki object id set
 14+ // e.g., key=hello, world&action=womquery,
 15+ // returns <match><id>1</id><type>text</type><start>20</start><end>30</end></match>
 16+ // in wiki object id="1", the text part of WOM node, char index start at 20 and end at 30
 17+ // for the paragraph instance, it will return id1, id2, id 3
 18+ // given the 'key', specify the returning object type, same result set to the previous api
 19+ // e.g., key=hello, world&action=womquery&return=sentence/paragraph/property value/template value/section...
 20+ // for the paragraph instance,
 21+ // return=sentence, it will return id3
 22+ // return=paragraph, it will return id1, id2
 23+ // given the 'key' and returning type, specify the context of required object, same return
 24+ // e.g., key=hello, world&action=womquery&return=sentence&xpath=/page/section[3]
 25+ // for the paragraph instance,
 26+ // return=paragraph, xpath=sentence/.., it will return id2
 27+
 28+ public function execute() {
 29+ global $wgUser;
 30+
 31+ $params = $this->extractRequestParams();
 32+ if ( is_null( $params['page'] ) )
 33+ $this->dieUsage( 'Must specify page title', 0 );
 34+ if ( is_null( $params['key'] ) )
 35+ $this->dieUsage( 'Must specify key', 1 );
 36+
 37+ $page = $params['page'];
 38+ $key = $params['key'];
 39+ $rid = $params['rid'];
 40+ $type = $params['type'];
 41+ $xpath = $params['xpath'];
 42+
 43+ $articleTitle = Title::newFromText( $page );
 44+ if ( !$articleTitle )
 45+ $this->dieUsage( "Can't create title object ($page)", 2 );
 46+
 47+ $article = new Article( $articleTitle );
 48+ if ( !$article->exists() )
 49+ $this->dieUsage( "Article doesn't exist ($page)", 3 );
 50+
 51+ if ( !$xpath ) {
 52+ $xpath = '/';
 53+ }
 54+ try {
 55+ $objs = WOMProcessor::getObjIdByXPath( $articleTitle, $xpath, $rid );
 56+ } catch ( Exception $e ) {
 57+ $err = $e->getMessage();
 58+ }
 59+
 60+ $result = array();
 61+
 62+ if ( isset( $err ) ) {
 63+ $result = array(
 64+ 'result' => 'Failure',
 65+ 'message' => array(),
 66+ );
 67+ $this->getResult()->setContent( $result['message'], $err );
 68+ } else {
 69+ $result['result'] = 'Success';
 70+
 71+ // pay attention to special xml tag, e.g., <property><value>...</value></property>
 72+ $result['return'] = array();
 73+ if ( $type == 'count' ) {
 74+ $count = 0;
 75+ foreach ( $objs as $id ) {
 76+ if ( $id == '' ) continue;
 77+ ++ $count;
 78+ }
 79+ $this->getResult()->setContent( $result['return'], $count );
 80+ } else {
 81+ $xml = '';
 82+ $page_obj = WOMProcessor::getPageObject( $articleTitle, $rid );
 83+ foreach ( $objs as $id ) {
 84+ if ( $id == '' ) continue;
 85+ $wobj = $page_obj->getObject( $id );
 86+ $result['return'][$id] = array();
 87+ if ( $type == 'xml' ) {
 88+ $xml .= "<{$id} xml:space=\"preserve\">{$wobj->toXML()}</{$id}>";
 89+// $this->getResult()->setContent( $result['return'][$id], $wobj->toXML() );
 90+ } else {
 91+ $this->getResult()->setContent( $result['return'][$id], $wobj->getWikiText() );
 92+ }
 93+ }
 94+ if ( $type == 'xml' ) {
 95+ header ( "Content-Type: application/rdf+xml" );
 96+ echo <<<OUTPUT
 97+<?xml version="1.0" encoding="UTF-8" ?>
 98+<api><womget result="Success"><return>
 99+{$xml}
 100+</return></womget></api>
 101+OUTPUT;
 102+ exit( 1 );
 103+ }
 104+ }
 105+ }
 106+ $this->getResult()->addValue( null, $this->getModuleName(), $result );
 107+ }
 108+
 109+ protected function getAllowedParams() {
 110+ return array (
 111+ 'page' => null,
 112+ 'key' => null,
 113+ 'xpath' => null,
 114+ 'type' => array(
 115+ ApiBase :: PARAM_DFLT => WOM_TYPE_SENTENCE,
 116+ ApiBase :: PARAM_TYPE => array(
 117+ WOM_TYPE_SECTION,
 118+ WOM_TYPE_PARAGRAPH,
 119+ WOM_TYPE_SENTENCE,
 120+ ),
 121+ ),
 122+ 'rid' => array (
 123+ ApiBase :: PARAM_TYPE => 'integer',
 124+ ApiBase :: PARAM_DFLT => 0,
 125+ ApiBase :: PARAM_MIN => 0
 126+ ),
 127+ );
 128+ }
 129+
 130+ protected function getParamDescription() {
 131+ return array (
 132+ 'page' => 'Title of the page to modify',
 133+ 'key' => 'query key',
 134+ 'xpath' => 'DOM-like xpath to locate WOM object instances (http://www.w3schools.com/xpath/xpath_syntax.asp)',
 135+ 'type' => array (
 136+ 'Object type to fetch useful wiki object data',
 137+ ),
 138+ 'rid' => 'Revision id of specified page - by dafault latest updated revision (0) is used',
 139+ );
 140+ }
 141+
 142+ protected function getDescription() {
 143+ return 'Call to get objects to Wiki Object Model';
 144+ }
 145+
 146+ protected function getExamples() {
 147+ return array (
 148+ 'api.php?action=womquery&page=Somepage&key=hello,world'
 149+ );
 150+ }
 151+
 152+ public function getVersion() {
 153+ return __CLASS__ . ': $Id$';
 154+ }
 155+}

Status & tagging log