PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/WikiObjectModel/includes/WOM_Processor.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 740 lines | 575 code | 119 blank | 46 comment | 131 complexity | dc285d3d33facab1c951b2d653e94884 MD5 | raw file
  1. <?php
  2. /**
  3. * @author ning
  4. */
  5. if ( !defined( 'MEDIAWIKI' ) ) {
  6. exit( 1 );
  7. }
  8. /**
  9. * Static class for accessing public static functions to generate and execute semantic queries
  10. * and to serialise their results.
  11. */
  12. class WOMProcessor {
  13. private static $isParsersRegistered = false;
  14. private static $parsers = array();
  15. private static $base_parser;
  16. private static function setupParsers() {
  17. if ( WOMProcessor::$isParsersRegistered ) return;
  18. global $wgOMParsers;
  19. foreach ( $wgOMParsers as $p ) {
  20. $parser = new $p();
  21. WOMProcessor::$parsers[$parser->getParserID()] = $parser;
  22. }
  23. WOMProcessor::$base_parser = WOMProcessor::$parsers[WOM_PARSER_ID_TEXT];
  24. WOMProcessor::$isParsersRegistered = true;
  25. }
  26. public static function getObjectParser( WikiObjectModel $obj ) {
  27. $fname = 'WikiObjectModel::getObjectParser (WOM)';
  28. wfProfileIn( $fname );
  29. if ( !WOMProcessor::$isParsersRegistered ) {
  30. WOMProcessor::setupParsers();
  31. }
  32. global $wgOMModelParserMapping;
  33. if ( isset( $wgOMModelParserMapping[$obj->getTypeID()] ) ) {
  34. $id = $wgOMModelParserMapping[$obj->getTypeID()];
  35. if ( isset( WOMProcessor::$parsers[$id] ) ) {
  36. wfProfileOut( $fname );
  37. return WOMProcessor::$parsers[$id];
  38. }
  39. }
  40. wfProfileOut( $fname );
  41. return WOMProcessor::$base_parser;
  42. }
  43. private static function applyObjID( WikiObjectModel $wom, WOMPageModel $root ) {
  44. $wom->setObjectID( $root->getNextId() );
  45. $root->addToPageObjectSet( $wom );
  46. if ( $wom instanceof WikiObjectModelCollection ) {
  47. foreach ( $wom->getObjects() as $obj ) {
  48. WOMProcessor::applyObjID( $obj, $root );
  49. }
  50. }
  51. }
  52. public static function parseToWOM( $text ) {
  53. $fname = 'WikiObjectModel::parseToWOM (WOM)';
  54. wfProfileIn( $fname );
  55. if ( !WOMProcessor::$isParsersRegistered ) {
  56. WOMProcessor::setupParsers();
  57. }
  58. $root = new WOMPageModel();
  59. WOMProcessor::parseNext( $text, $root, $root );
  60. WOMProcessor::parseSentences( $root );
  61. WOMProcessor::applyObjID( $root, $root );
  62. wfProfileOut( $fname );
  63. return $root;
  64. }
  65. /**
  66. * Special case, sentence is not standard wiki object
  67. *
  68. * @param WOMPageModel $rootObj
  69. */
  70. private static function parseSentences( WikiObjectModelCollection $wom ) {
  71. global $wgOMSentenceObjectTypes;
  72. $in_sentence = false;
  73. $new_objs = array();
  74. $sentenceObj = null;
  75. foreach ( $wom->getObjects() as $id => $obj ) {
  76. if ( in_array( $obj->getTypeID(), $wgOMSentenceObjectTypes ) ) {
  77. if ( !$in_sentence ) {
  78. $sentenceObj = new WOMSentenceModel();
  79. $new_objs[] = $sentenceObj;
  80. $in_sentence = true;
  81. }
  82. $sentenceObj->insertObject( $obj );
  83. // parse sentence break
  84. if ( $obj->getTypeID() == WOM_TYPE_TEXT ) {
  85. $text = $obj->getWikiText();
  86. $offset = 0;
  87. $len = strlen( $text );
  88. // FIXME: sentence algorithm here, for now, just think of
  89. // \n
  90. // [.?!]((['"]|'{2,6})?)<space>
  91. // shall think of other language, e.g., Chinese
  92. $r = preg_match_all( '/(\n[^\n])|(([\.!?](([\'"]|\'{2,6})?))([ \t]))/',
  93. $text, $ms, PREG_SET_ORDER | PREG_OFFSET_CAPTURE );
  94. if ( $r ) {
  95. foreach ( $ms as $m ) {
  96. if ( $m[1][1] >= 0 ) {
  97. $end = $m[0][1] + 1;
  98. } else {
  99. $end = $m[0][1] + strlen( $m[0][0] );
  100. }
  101. $obj->setText( substr( $text, $offset, $end - $offset ) );
  102. $offset = $end;
  103. if ( $end == $len ) break;
  104. $sentenceObj = new WOMSentenceModel();
  105. $new_objs[] = $sentenceObj;
  106. $obj = new WOMTextModel( substr( $text, $end ) );
  107. $sentenceObj->insertObject( $obj );
  108. }
  109. }
  110. }
  111. } else {
  112. $in_sentence = false;
  113. $sentenceObj = null;
  114. if ( $obj->getTypeID() == WOM_TYPE_HTMLTAG ) {
  115. // special case, html tag
  116. } elseif ( $obj instanceof WikiObjectModelCollection ) {
  117. WOMProcessor::parseSentences( $obj );
  118. }
  119. $new_objs[] = $obj;
  120. }
  121. }
  122. $wom->reset();
  123. foreach ( $new_objs as $obj ) {
  124. $wom->insertObject( $obj );
  125. }
  126. }
  127. private static function assemble( &$next_obj ) {
  128. $parentObj = $next_obj->getParent();
  129. $brother = $parentObj->getLastObject();
  130. if ( $next_obj->getTypeID() == WOM_TYPE_TEXT &&
  131. $brother != null && $brother->getTypeID() == WOM_TYPE_TEXT ) {
  132. // special case, merge text token to previous text node
  133. $brother->append( $next_obj->getWikiText() );
  134. } else {
  135. $parentObj->insertObject( $next_obj );
  136. }
  137. }
  138. private static function parseNext( $text, WikiObjectModelCollection $parentObj, WOMPageModel $rootObj, &$offset = 0, $parserInstance = null ) {
  139. // $fname = 'WikiObjectModel::parseNext (WOM)';
  140. // wfProfileIn( $fname );
  141. $len = strlen( $text );
  142. while ( $offset < $len ) {
  143. if ( WOMProcessor::getObjectParser( $parentObj ) != null ) {
  144. $objectClosed = WOMProcessor::getObjectParser( $parentObj )
  145. ->isObjectClosed( $parentObj, $text, $offset );
  146. if ( $objectClosed !== false ) {
  147. $offset += $objectClosed;
  148. // wfProfileOut( $fname );
  149. return;
  150. }
  151. }
  152. $result = null;
  153. if ( $parserInstance == null ) {
  154. $parserInstance2 = null;
  155. foreach ( WOMProcessor::$parsers as $parser ) {
  156. $parser_res = $parser->parseNext( $text, $parentObj, $offset );
  157. if ( $parser_res == null ) continue;
  158. if ( $parserInstance2 == null || $parser->subclassOf( $parserInstance2 ) ) {
  159. $parserInstance2 = $parser;
  160. $result = $parser_res;
  161. }
  162. }
  163. if ( $parserInstance2 == null ) {
  164. $parserInstance2 = WOMProcessor::$base_parser;
  165. $result = $parserInstance2->parseNext( $text, $parentObj, $offset );
  166. }
  167. } else {
  168. $parserInstance2 = $parserInstance;
  169. $result = $parserInstance->parseNext( $text, $parentObj, $offset );
  170. if ( $result == null ) {
  171. // FIXME: just omit current char, this will not fit for Wiki parser
  172. ++ $offset;
  173. continue;
  174. }
  175. }
  176. $next_obj = $result['obj'];
  177. // just reparse
  178. if ( $next_obj->getParent() != null && $next_obj->getParent() != $parentObj ) {
  179. // wfProfileOut( $fname );
  180. return;
  181. }
  182. $offset += $result['len'];
  183. if ( $next_obj->getParent() == null ) {
  184. $next_obj->setParent( $parentObj );
  185. }
  186. WOMProcessor::assemble( $next_obj );
  187. if ( $next_obj->isCollection() && !( isset( $result['closed'] ) && $result['closed'] ) ) {
  188. $collection_start = $offset;
  189. $d = WOMProcessor::parseNext( $text, $next_obj, $rootObj, $offset,
  190. ( ( $parserInstance2 != null && isset( WOMProcessor::$parsers[$parserInstance2->getSubParserID()] ) ) ?
  191. WOMProcessor::$parsers[$parserInstance2->getSubParserID()] :
  192. null ) );
  193. if ( $d == 100 && $parserInstance2->isObjectClosed( $next_obj, $text, $offset ) === false ) {
  194. // rollback
  195. $p = WOMProcessor::getObjectParser( $parentObj );
  196. if ( $p != null && $p->isObjectClosed( $parentObj, $text, $offset ) === false ) {
  197. return $d;
  198. }
  199. $parentObj->rollback();
  200. $offset = $collection_start - $result['len'];
  201. $result = WOMProcessor::$base_parser->parseNext( $text, $parentObj, $offset );
  202. $offset += $result['len'];
  203. $next_obj = $result['obj'];
  204. $next_obj->setParent( $parentObj );
  205. WOMProcessor::assemble( $next_obj );
  206. } else {
  207. $next_obj->updateOnNodeClosed();
  208. }
  209. }
  210. }
  211. // FIXME: just announce that we've reached the end of wiki text
  212. return 100;
  213. // wfProfileOut( $fname );
  214. }
  215. public static function getTemplateEditor( $template_name, $form_name = null ) {
  216. $fname = 'WikiObjectModel::getTemplateEditor (WOM)';
  217. wfProfileIn( $fname );
  218. wfProfileOut( $fname );
  219. return $result;
  220. }
  221. public static function getTemplateFieldEditor( $template_name, $field ) {
  222. $fname = 'WikiObjectModel::getTemplateFieldEditor (WOM)';
  223. wfProfileIn( $fname );
  224. wfProfileOut( $fname );
  225. return array(
  226. 'type' => ( is_array( $result ) ? $result[0] : $result ),
  227. 'possible_values' => $possible_values,
  228. 'is_list' => false,
  229. );
  230. }
  231. public static function getPropertyEditor( $property ) {
  232. $fname = 'WikiObjectModel::getPropertyEditor (WOM)';
  233. wfProfileIn( $fname );
  234. $proptitle = Title::makeTitleSafe( SMW_NS_PROPERTY, $property );
  235. if ( $proptitle === NULL ) {
  236. wfProfileOut( $fname );
  237. return null;
  238. }
  239. $property = SMWPropertyValue::makeUserProperty( $property );
  240. $store = smwfGetStore();
  241. if ( class_exists( 'SMWPropertyValue' ) ) {
  242. $allowed_values = $store->getPropertyValues( $proptitle, SMWPropertyValue::makeUserProperty( "Allows value" ) );
  243. } else {
  244. $allowed_values = $store->getSpecialValues( $proptitle, SMW_SP_POSSIBLE_VALUE );
  245. }
  246. $possible_values = array();
  247. foreach ( $allowed_values as $value ) {
  248. $possible_values[] = html_entity_decode( $value->getWikiValue() );
  249. }
  250. if ( count( $possible_values ) > 0 ) {
  251. $result = WOMProcessor::getSemanticEditor( 'enumeration' );
  252. } else {
  253. $result = WOMProcessor::getSemanticEditor( $property->getPropertyTypeID() );
  254. }
  255. wfProfileOut( $fname );
  256. return array(
  257. 'type' => ( is_array( $result ) ? $result[0] : $result ),
  258. 'possible_values' => $possible_values,
  259. 'is_list' => false,
  260. );
  261. }
  262. private static function getSemanticEditor( $semantic_type_id ) {
  263. if ( $semantic_type_id == '_str' ||
  264. $semantic_type_id == '_num' ||
  265. $semantic_type_id == '_tel' ||
  266. $semantic_type_id == '_uri' ||
  267. $semantic_type_id == '_ema' ) {
  268. return array( 'text' );
  269. } elseif ( $semantic_type_id == '_txt' || $semantic_type_id == '_cod' ) {
  270. return array( 'textarea' );
  271. } elseif ( $semantic_type_id == '_boo' ) {
  272. return array( 'checkbox' );
  273. } elseif ( $semantic_type_id == '_dat' ) {
  274. return array( 'date', 'datetime', 'datetime with timezone', 'year' );
  275. } elseif ( $semantic_type_id == 'enumeration' ) {
  276. // not real type, from semantic allow value
  277. return array( 'dropdown', 'radiobutton' );
  278. } elseif ( $semantic_type_id == '_wpg' ) {
  279. return array( 'text' );
  280. } else { // blank or an unknown type
  281. // SMW 1.5
  282. // '_geo' => 'Geographic coordinate', // name of the geocoord type
  283. // '_tem' => 'Temperature', // name of the temperature type
  284. // '_anu' => 'Annotation URI', // name of the annotation URI type (OWL annotation property)
  285. // '_rec' => 'Record', // name of record data type
  286. return array( 'textarea', 'text' );
  287. }
  288. }
  289. public static function getPageObject( $title, $rid = 0 ) {
  290. $fname = 'WikiObjectModel::getPageObject (WOM)';
  291. wfProfileIn( $fname );
  292. $revision = Revision::newFromTitle( $title, $rid );
  293. if ( $revision == null ) {
  294. throw new MWException( __METHOD__ . ": Page not exist '{$title} ({$rid})'" );
  295. }
  296. $content = $revision->getText();
  297. $wom = WOMProcessor::parseToWOM( $content );
  298. $wom->setTitle( $title );
  299. $wom->setRevisionID( $revision->getId() );
  300. wfProfileOut( $fname );
  301. return $wom;
  302. }
  303. public static function getObjIdByXPath( $title, $xpath, $rid = 0 ) {
  304. $fname = 'WikiObjectModel::getObjIdByXPath (WOM)';
  305. wfProfileIn( $fname );
  306. $xml = WOMProcessor::getPageObject( $title, $rid )->toXML();
  307. $xObj = simplexml_load_string( $xml );
  308. try {
  309. $objs = $xObj->xpath( $xpath );
  310. } catch ( Exception $e ) {
  311. throw new MWException( __METHOD__ . ": {$e->getMessage()}" );
  312. }
  313. $ret = array();
  314. if ( $objs ) {
  315. foreach ( $objs as $o ) {
  316. $ret[] = strval( $o['id'] );
  317. }
  318. } else {
  319. throw new MWException( __METHOD__ . ": XML element not found in {$title} ({$rid}), xpath: {$xpath}" );
  320. }
  321. wfProfileOut( $fname );
  322. return $ret;
  323. }
  324. public static function getSubObjectsByParentId( $title, $obj_id, $rid = 0 ) {
  325. $fname = 'WikiObjectModel::getSubPageObjectsByParentId (WOM)';
  326. wfProfileIn( $fname );
  327. $wom = WOMProcessor::getPageObject( $title, $rid );
  328. $obj = $wom->getObject( $obj_id );
  329. wfProfileOut( $fname );
  330. if ( $obj instanceof WikiObjectModelCollection )
  331. return $obj->getObjects();
  332. else
  333. return null;
  334. }
  335. private static function getPageObjectsByTypeID( $type_id, $title, $rid = 0 ) {
  336. $fname = 'WikiObjectModel::getPageObjectsByTypeID (WOM)';
  337. wfProfileIn( $fname );
  338. $wom = WOMProcessor::getPageObject( $title, $rid );
  339. $result = $wom->getObjectsByTypeID( $type_id );
  340. wfProfileOut( $fname );
  341. return $result;
  342. }
  343. public static function getPageTemplates( $title, $name = '', $rid = 0 ) {
  344. $fname = 'WikiObjectModel::getPageTemplates (WOM)';
  345. wfProfileIn( $fname );
  346. $result = WOMProcessor::getPageObjectsByTypeID(
  347. WOM_TYPE_TEMPLATE, $title, $rid );
  348. if ( $name == '' ) {
  349. $result2 = $result;
  350. } else {
  351. $result2 = array();
  352. foreach ( $result as $id => $obj ) {
  353. if ( $obj->getName() == $name ) {
  354. $result2[$id] = $obj;
  355. }
  356. }
  357. }
  358. wfProfileOut( $fname );
  359. return $result2;
  360. }
  361. public static function getPageCategories( $title, $rid = 0 ) {
  362. $fname = 'WikiObjectModel::getPageCategories (WOM)';
  363. wfProfileIn( $fname );
  364. $result = WOMProcessor::getPageObjectsByTypeID(
  365. WOM_TYPE_CATEGORY, $title, $rid );
  366. wfProfileOut( $fname );
  367. return $result;
  368. }
  369. public static function getPageLinks( $title, $rid = 0 ) {
  370. $fname = 'WikiObjectModel::getPageLinks (WOM)';
  371. wfProfileIn( $fname );
  372. $result = WOMProcessor::getPageObjectsByTypeID(
  373. WOM_TYPE_LINK, $title, $rid );
  374. wfProfileOut( $fname );
  375. return $result;
  376. }
  377. public static function getPageProperties( $title, $rid = 0 ) {
  378. $fname = 'WikiObjectModel::getPageProperties (WOM)';
  379. wfProfileIn( $fname );
  380. // do not return properties which are binding template fields, in current version
  381. $result = WOMProcessor::getPageObjectsByTypeID(
  382. WOM_TYPE_PROPERTY, $title, $rid );
  383. wfProfileOut( $fname );
  384. return $result;
  385. }
  386. public static function getParserFunctions( $title, $function_key = '', $rid = 0 ) {
  387. $fname = 'WikiObjectModel::getParserFunctions (WOM)';
  388. wfProfileIn( $fname );
  389. $result = WOMProcessor::getPageObjectsByTypeID(
  390. WOM_TYPE_PARSERFUNCTION, $title, $rid );
  391. if ( $function_key == '' ) {
  392. $result2 = $result;
  393. } else {
  394. $result2 = array();
  395. foreach ( $result as $id => $obj ) {
  396. if ( $obj->getFunctionKey() == $function_key ) {
  397. $result2[$id] = $obj;
  398. }
  399. }
  400. }
  401. wfProfileOut( $fname );
  402. return $result2;
  403. }
  404. public static function insertPageObject( $object, $title, $obj_id = '', $summary = '', $revision_id = 0, $force_update = true ) {
  405. $fname = 'WikiObjectModel::insertPageObject (WOM)';
  406. wfProfileIn( $fname );
  407. if ( $revision_id > 0 ) {
  408. $revision = Revision::newFromTitle( $title );
  409. $id = $revision->getId();
  410. if ( $id != $revision_id && !$force_update ) {
  411. throw new MWException( __METHOD__ . ": Page revision id does not match '{$title} ({$revision_id}) - {$id}'" );
  412. wfProfileOut( $fname );
  413. return;
  414. }
  415. }
  416. $wom = WOMProcessor::getPageObject( $title, $revision_id );
  417. $wom->insertPageObject( $object, $obj_id );
  418. // save to wiki
  419. $article = new Article( $title );
  420. $content = $wom->getWikiText();
  421. $article->doEdit( $content, $summary );
  422. wfProfileOut( $fname );
  423. }
  424. public static function appendPageObject( $object, $title, $obj_id = '', $summary = '', $revision_id = 0, $force_update = true ) {
  425. $fname = 'WikiObjectModel::appendPageObject (WOM)';
  426. wfProfileIn( $fname );
  427. if ( $revision_id > 0 ) {
  428. $revision = Revision::newFromTitle( $title );
  429. $id = $revision->getId();
  430. if ( $id != $revision_id && !$force_update ) {
  431. throw new MWException( __METHOD__ . ": Page revision id does not match '{$title} ({$revision_id}) - {$id}'" );
  432. wfProfileOut( $fname );
  433. return;
  434. }
  435. }
  436. $wom = WOMProcessor::getPageObject( $title, $revision_id );
  437. $parent = $wom->getObject( $obj_id );
  438. if ( !( $parent instanceof WikiObjectModelCollection ) ) {
  439. throw new MWException( __METHOD__ . ": Object is not a collection object '{$title} ({$revision_id}) - {$obj_id}'" );
  440. wfProfileOut( $fname );
  441. return;
  442. }
  443. $wom->appendChildObject( $object, $obj_id );
  444. // save to wiki
  445. $article = new Article( $title );
  446. $content = $wom->getWikiText();
  447. $article->doEdit( $content, $summary );
  448. wfProfileOut( $fname );
  449. }
  450. public static function updatePageObject( $object, $title, $obj_id, $summary = '', $revision_id = 0, $force_update = true ) {
  451. $fname = 'WikiObjectModel::updatePageObject (WOM)';
  452. wfProfileIn( $fname );
  453. if ( $revision_id > 0 ) {
  454. $revision = Revision::newFromTitle( $title );
  455. $id = $revision->getId();
  456. if ( $id != $revision_id && !$force_update ) {
  457. throw new MWException( __METHOD__ . ": Page revision id does not match '{$title} ({$revision_id}) - {$id}'" );
  458. wfProfileOut( $fname );
  459. return;
  460. }
  461. }
  462. $wom = WOMProcessor::getPageObject( $title, $revision_id );
  463. $wom->updatePageObject( $object, $obj_id );
  464. // save to wiki
  465. $article = new Article( $title );
  466. $content = $wom->getWikiText();
  467. $article->doEdit( $content, $summary );
  468. wfProfileOut( $fname );
  469. }
  470. public static function removePageObject( $title, $obj_id, $summary = '', $revision_id = 0, $force_update = true ) {
  471. $fname = 'WikiObjectModel::removePageObject (WOM)';
  472. wfProfileIn( $fname );
  473. if ( $revision_id > 0 ) {
  474. $revision = Revision::newFromTitle( $title );
  475. $id = $revision->getId();
  476. if ( $id != $revision_id && !$force_update ) {
  477. throw new MWException( __METHOD__ . ": Page revision id does not match '{$title} ({$revision_id}) - {$id}'" );
  478. wfProfileOut( $fname );
  479. return;
  480. }
  481. }
  482. $wom = WOMProcessor::getPageObject( $title, $revision_id );
  483. $wom->removePageObject( $obj_id );
  484. // save to wiki
  485. $article = new Article( $title );
  486. $content = $wom->getWikiText();
  487. $article->doEdit( $content, $summary );
  488. wfProfileOut( $fname );
  489. }
  490. public static function insertPageText( $text, $title, $obj_id = '', $summary = '', $revision_id = 0, $force_update = true ) {
  491. $fname = 'WikiObjectModel::insertPageText (WOM)';
  492. wfProfileIn( $fname );
  493. if ( $revision_id > 0 ) {
  494. $revision = Revision::newFromTitle( $title );
  495. $id = $revision->getId();
  496. if ( $id != $revision_id && !$force_update ) {
  497. throw new MWException( __METHOD__ . ": Page revision id does not match '{$title} ({$revision_id}) - {$id}'" );
  498. wfProfileOut( $fname );
  499. return;
  500. }
  501. }
  502. $wom = WOMProcessor::getPageObject( $title, $revision_id );
  503. $text = WOMProcessor::getValidText( $text, $wom->getObject( $obj_id )->getParent(), $wom );
  504. // no need to parse or merge object model but use text
  505. $wom->insertPageObject( new WOMTextModel( $text ), $obj_id );
  506. // save to wiki
  507. $article = new Article( $title );
  508. $content = $wom->getWikiText();
  509. $article->doEdit( $content, $summary );
  510. wfProfileOut( $fname );
  511. }
  512. public static function appendPageText( $text, $title, $obj_id = '', $summary = '', $revision_id = 0, $force_update = true ) {
  513. $fname = 'WikiObjectModel::appendPageText (WOM)';
  514. wfProfileIn( $fname );
  515. if ( $revision_id > 0 ) {
  516. $revision = Revision::newFromTitle( $title );
  517. $id = $revision->getId();
  518. if ( $id != $revision_id && !$force_update ) {
  519. throw new MWException( __METHOD__ . ": Page revision id does not match '{$title} ({$revision_id}) - {$id}'" );
  520. wfProfileOut( $fname );
  521. return;
  522. }
  523. }
  524. $wom = WOMProcessor::getPageObject( $title, $revision_id );
  525. $parent = $wom->getObject( $obj_id );
  526. if ( !( $parent instanceof WikiObjectModelCollection ) ) {
  527. throw new MWException( __METHOD__ . ": Object is not a collection object '{$title} ({$revision_id}) - {$obj_id}'" );
  528. wfProfileOut( $fname );
  529. return;
  530. }
  531. $text = WOMProcessor::getValidText( $text, $parent, $wom );
  532. // no need to parse or merge object model but use text
  533. $wom->appendChildObject( new WOMTextModel( $text ), $obj_id );
  534. // save to wiki
  535. $article = new Article( $title );
  536. $content = $wom->getWikiText();
  537. $article->doEdit( $content, $summary );
  538. wfProfileOut( $fname );
  539. }
  540. public static function updatePageText( $text, $title, $obj_id, $summary = '', $revision_id = 0, $force_update = true ) {
  541. $fname = 'WikiObjectModel::updatePageText (WOM)';
  542. wfProfileIn( $fname );
  543. if ( $revision_id > 0 ) {
  544. $revision = Revision::newFromTitle( $title );
  545. $id = $revision->getId();
  546. if ( $id != $revision_id && !$force_update ) {
  547. throw new MWException( __METHOD__ . ": Page revision id does not match '{$title} ({$revision_id}) - {$id}'" );
  548. wfProfileOut( $fname );
  549. return;
  550. }
  551. }
  552. $wom = WOMProcessor::getPageObject( $title, $revision_id );
  553. $text = WOMProcessor::getValidText( $text, $wom->getObject( $obj_id )->getParent(), $wom );
  554. // no need to parse or merge object model but use text
  555. $wom->updatePageObject( new WOMTextModel( $text ), $obj_id );
  556. // save to wiki
  557. $article = new Article( $title );
  558. $content = $wom->getWikiText();
  559. $article->doEdit( $content, $summary );
  560. wfProfileOut( $fname );
  561. }
  562. private static function getValidText( $text, $parent, $wom ) {
  563. if ( $parent != null ) {
  564. $parserId = WOMProcessor::getObjectParser( $parent )->getSubParserID();
  565. if ( $parserId != '' ) {
  566. $parser = WOMProcessor::$parsers[$parserId];
  567. $offset = 0;
  568. $p2 = clone ( $parent );
  569. $p2->reset();
  570. WOMProcessor::parseNext( $text, $p2, $wom, $offset, $parser );
  571. $text = '';
  572. foreach ( $p2->getObjects() as $obj ) {
  573. $text .= $obj->getWikiText();
  574. }
  575. }
  576. }
  577. return $text;
  578. }
  579. public static function getToc( $title, $rid = 0 ) {
  580. $fname = 'WikiObjectModel::getToc (WOM)';
  581. wfProfileIn( $fname );
  582. $wom = WOMProcessor::getPageObject( $title, $revision_id );
  583. $arr = array();
  584. WOMProcessor::saveToToc( $wom, $arr );
  585. wfProfileOut( $fname );
  586. return $arr;
  587. }
  588. private static function saveToToc( $wom, &$arr ) {
  589. foreach ( $wom->getObjects() as $obj ) {
  590. if ( $obj->getTypeID() == WOM_TYPE_SECTION ) {
  591. $sec = array( 'section' => $obj->getName(), 'sub' => array() );
  592. WOMProcessor::saveToToc( $obj, $sec['sub'] );
  593. $arr[] = $sec;
  594. }
  595. }
  596. }
  597. public static function objectsToWikiText( $objs ) {
  598. $fname = 'WikiObjectModel::objectsToWikiText (WOM)';
  599. wfProfileIn( $fname );
  600. $result = '';
  601. if ( is_array( $objs ) ) {
  602. foreach ( $objs as $obj ) {
  603. $result .= $obj->getWikiText();
  604. }
  605. } else {
  606. $result .= $objs->getWikiText();
  607. }
  608. wfProfileOut( $fname );
  609. return $result;
  610. }
  611. public static function objectToWikiText( $title, $obj_id, $rid = 0 ) {
  612. $fname = 'WikiObjectModel::objectToWikiText (WOM)';
  613. wfProfileIn( $fname );
  614. $wom = WOMProcessor::getPageObject( $title, $revision_id );
  615. $obj = $wom->getObject( $obj_id );
  616. // shall through error, not for now
  617. $result = isset( $obj ) ? $obj->getWikiText() : "";
  618. wfProfileOut( $fname );
  619. return $result;
  620. }
  621. }