PageRenderTime 28ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/SemanticForms/specials/SF_FormEdit.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 376 lines | 244 code | 67 blank | 65 comment | 81 complexity | 36fc1269198f36cce50a84d55cbefcf7 MD5 | raw file
  1. <?php
  2. /**
  3. * Displays a pre-defined form for either creating a new page or editing an
  4. * existing one.
  5. *
  6. * @author Yaron Koren
  7. * @file
  8. * @ingroup SF
  9. */
  10. /**
  11. * @ingroup SFSpecialPages
  12. */
  13. class SFFormEdit extends SpecialPage {
  14. public $mTarget;
  15. public $mForm;
  16. public $mError;
  17. /**
  18. * Constructor
  19. */
  20. function __construct() {
  21. parent::__construct( 'FormEdit' );
  22. SFUtils::loadMessages();
  23. }
  24. function execute( $query, $redirectOnError = true ) {
  25. global $wgRequest, $wgOut;
  26. wfProfileIn( __METHOD__ );
  27. $this->setHeaders();
  28. $this->mForm = $wgRequest->getVal( 'form' );
  29. $this->mTarget = $wgRequest->getVal( 'target' );
  30. // if query string did not contain these variables, try the URL
  31. if ( ! $this->mForm && ! $this->mTarget ) {
  32. $queryparts = explode( '/', $query, 2 );
  33. $this->mForm = isset( $queryparts[0] ) ? $queryparts[0] : '';
  34. $this->mTarget = isset( $queryparts[1] ) ? $queryparts[1] : '';
  35. }
  36. wfRunHooks( 'sfSetTargetName', array( &$this->mTarget, $query ) );
  37. $alt_forms = $wgRequest->getArray( 'alt_form' );
  38. $msg = self::printForm( $this->mForm, $this->mTarget, $alt_forms, $redirectOnError );
  39. if ( $msg ) {
  40. // some error occurred
  41. $msgdata = null;
  42. if ( is_array( $msg ) ) {
  43. if ( count( $msg ) > 1 ) {
  44. $msgdata = $msg[ 1 ];
  45. }
  46. $msg = $msg[ 0 ];
  47. }
  48. $this->mError = wfMsg( $msg, $msgdata );
  49. $wgOut->addHTML( Xml::element( 'p', array( 'class' => 'error' ), $this->mError ) );
  50. } else {
  51. $this->mError = null;
  52. }
  53. wfProfileOut( __METHOD__ );
  54. }
  55. static function printAltFormsList( $alt_forms, $target_name ) {
  56. $text = "";
  57. $fe = SpecialPage::getPage( 'FormEdit' );
  58. $fe_url = $fe->getTitle()->getFullURL();
  59. $i = 0;
  60. foreach ( $alt_forms as $alt_form ) {
  61. if ( $i++ > 0 ) { $text .= ', '; }
  62. $text .= "<a href=\"$fe_url/$alt_form/$target_name\">" . str_replace( '_', ' ', $alt_form ) . '</a>';
  63. }
  64. return $text;
  65. }
  66. static function makeRandomNumber() {
  67. srand( time() );
  68. return rand() % 1000000;
  69. }
  70. static function printForm( &$form_name, &$target_name, $alt_forms = array(), $redirectOnError = false ) {
  71. global $wgOut, $wgRequest, $wgUser, $sfgFormPrinter;
  72. SFUtils::loadMessages();
  73. // If we have no form name we might as well stop right away
  74. if ( $form_name == '' ) {
  75. return 'sf_formedit_badurl';
  76. }
  77. // initialize some variables
  78. $target_title = null;
  79. $page_name_formula = null;
  80. $form_title = Title::makeTitleSafe( SF_NS_FORM, $form_name );
  81. $form_article = new Article( $form_title, 0 );
  82. $form_definition = $form_article->getContent();
  83. $form_definition = StringUtils::delimiterReplace( '<noinclude>', '</noinclude>', '', $form_definition );
  84. if ( $target_name == '' ) {
  85. // parse the form to see if it has a 'page name' value set
  86. $matches;
  87. if ( preg_match( '/{{{info.*page name\s*=\s*(.*)}}}/m', $form_definition, $matches ) ) {
  88. $page_name_elements = SFUtils::getFormTagComponents( $matches[1] );
  89. $page_name_formula = $page_name_elements[0];
  90. } elseif ( count( $alt_forms ) == 0 ) {
  91. return 'sf_formedit_badurl';
  92. }
  93. } else {
  94. $target_title = Title::newFromText( $target_name );
  95. if ( $target_title && $target_title->exists() ) {
  96. if ( $wgRequest->getVal( 'query' ) == 'true' ) {
  97. $page_contents = null;
  98. //$page_is_source = false;
  99. } else {
  100. $target_article = new Article( $target_title, 0 );
  101. $page_contents = $target_article->getContent();
  102. //$page_is_source = true;
  103. }
  104. } else {
  105. $target_name = str_replace( '_', ' ', $target_name );
  106. }
  107. }
  108. if ( ! $form_title || ! $form_title->exists() ) {
  109. if ( count( $alt_forms ) > 0 ) {
  110. $text = '<div class="infoMessage">'
  111. . wfMsg( 'sf_formedit_altformsonly' ) . ' '
  112. . self::printAltFormsList( $alt_forms, $form_name )
  113. . "</div>\n";
  114. } else {
  115. $text = Xml::tags( 'p', array( 'class' => 'error' ), wfMsg( 'sf_formstart_badform', SFUtils::linkText( SF_NS_FORM, $form_name ) ) ) . "\n";
  116. }
  117. } elseif ( $target_name == '' && $page_name_formula == '' ) {
  118. $text = Xml::element( 'p', array( 'class' => 'error' ), wfMsg( 'sf_formedit_badurl' ) ) . "\n";
  119. } else {
  120. $save_page = $wgRequest->getCheck( 'wpSave' );
  121. $preview_page = $wgRequest->getCheck( 'wpPreview' );
  122. $diff_page = $wgRequest->getCheck( 'wpDiff' );
  123. $form_submitted = ( $save_page || $preview_page || $diff_page );
  124. // get 'preload' query value, if it exists
  125. if ( ! $form_submitted ) {
  126. if ( $wgRequest->getCheck( 'preload' ) ) {
  127. $page_is_source = true;
  128. $page_contents = SFFormUtils::getPreloadedText( $wgRequest->getVal( 'preload' ) );
  129. } else {
  130. // let other extensions preload the page, if they want
  131. wfRunHooks( 'sfEditFormPreloadText', array( &$page_contents, $target_title, $form_title ) );
  132. $page_is_source = ( $page_contents != null );
  133. }
  134. } else {
  135. $page_is_source = false;
  136. $page_contents = null;
  137. }
  138. list ( $form_text, $javascript_text, $data_text, $form_page_title, $generated_page_name ) =
  139. $sfgFormPrinter->formHTML( $form_definition, $form_submitted, $page_is_source, $form_article->getID(), $page_contents, $target_name, $page_name_formula );
  140. // Before we do anything else, set the form header
  141. // title - this needs to be done after formHTML() is
  142. // called, because otherwise it doesn't take hold
  143. // for some reason if the form is disabled.
  144. if ( empty( $target_title ) ) {
  145. $s = wfMsg( 'sf_formedit_createtitlenotarget', $form_title->getText() );
  146. } elseif ( $target_title->exists() ) {
  147. $s = wfMsg( 'sf_formedit_edittitle', $form_title->getText(), $target_title->getPrefixedText() );
  148. } else {
  149. $s = wfMsg( 'sf_formedit_createtitle', $form_title->getText(), $target_title->getPrefixedText() );
  150. }
  151. $wgOut->setPageTitle( $s );
  152. if ( $form_submitted ) {
  153. if ( $page_name_formula != '' ) {
  154. $target_name = $generated_page_name;
  155. // prepend a super-page, if one was specified
  156. if ( $wgRequest->getCheck( 'super_page' ) ) {
  157. $target_name = $wgRequest->getVal( 'super_page' ) . '/' . $target_name;
  158. }
  159. // prepend a namespace, if one was specified
  160. if ( $wgRequest->getCheck( 'namespace' ) ) {
  161. $target_name = $wgRequest->getVal( 'namespace' ) . ':' . $target_name;
  162. }
  163. // replace "unique number" tag with one
  164. // that won't get erased by the next line
  165. $target_name = preg_replace( '/<unique number(.*)>/', '{num\1}', $target_name, 1 );
  166. // if any formula stuff is still in the
  167. // name after the parsing, just remove it
  168. $target_name = StringUtils::delimiterReplace( '<', '>', '', $target_name );
  169. // now run the parser on it
  170. global $wgParser;
  171. // ...but first, replace spaces back
  172. // with underlines, in case a magic word
  173. // or parser function name contains
  174. // underlines - hopefully this won't
  175. // cause problems of its own
  176. $target_name = str_replace( ' ', '_', $target_name );
  177. $target_name = $wgParser->preprocess( $target_name, $wgOut->getTitle(), ParserOptions::newFromUser( null ) );
  178. $title_number = "";
  179. $isRandom = false;
  180. if ( strpos( $target_name, '{num' ) ) {
  181. // random number
  182. if ( preg_match( '/{num;random}/', $target_name, $matches ) ) {
  183. $isRandom = true;
  184. $title_number = self::makeRandomNumber();
  185. } else {
  186. // get unique number start value
  187. // from target name; if it's not
  188. // there, or it's not a positive
  189. // number, start it out as blank
  190. preg_match( '/{num.*start[_]*=[_]*([^;]*).*}/', $target_name, $matches );
  191. if ( count( $matches ) == 2 && is_numeric( $matches[ 1 ] ) && $matches[ 1 ] >= 0 ) {
  192. // the "start" value"
  193. $title_number = $matches[ 1 ];
  194. }
  195. }
  196. // set target title
  197. $target_title = Title::newFromText( preg_replace( '/{num.*}/', $title_number, $target_name ) );
  198. // if title exists already
  199. // cycle through numbers for
  200. // this tag until we find one
  201. // that gives a nonexistent page
  202. // title
  203. while ( $target_title->exists() ) {
  204. if ( $isRandom ) {
  205. $title_number = self::makeRandomNumber();
  206. }
  207. // if title number is blank,
  208. // change it to 2; otherwise,
  209. // increment it, and if necessary
  210. // pad it with leading 0s as well
  211. elseif ( $title_number == "" ) {
  212. $title_number = 2;
  213. } else {
  214. $title_number = str_pad( $title_number + 1, strlen( $title_number ), '0', STR_PAD_LEFT );
  215. }
  216. $target_title = Title::newFromText( preg_replace( '/{num.*}/', $title_number, $target_name ) );
  217. }
  218. $target_name = $target_title->getPrefixedText();
  219. } else {
  220. $target_title = Title::newFromText( $target_name );
  221. }
  222. }
  223. if ( is_null( $target_title ) ) {
  224. if ( $target_name ) return array ( 'sf_formstart_badtitle' , array( $target_name ) );
  225. else return 'sf_formedit_emptytitle';
  226. }
  227. if ( $save_page ) {
  228. // Set up all the variables for the
  229. // page save.
  230. $data = array(
  231. 'wpTextbox1' => $data_text,
  232. 'wpSummary' => $wgRequest->getVal( 'wpSummary' ),
  233. 'wpStarttime' => $wgRequest->getVal( 'wpStarttime' ),
  234. 'wpEdittime' => $wgRequest->getVal( 'wpEdittime' ),
  235. 'wpEditToken' => $wgUser->isLoggedIn() ? $wgUser->editToken() : EDIT_TOKEN_SUFFIX,
  236. 'wpSave' => '',
  237. 'action' => 'submit',
  238. );
  239. if ( $wgRequest->getCheck( 'wpMinoredit' ) ) {
  240. $data['wpMinoredit'] = true;
  241. }
  242. if ( $wgRequest->getCheck( 'wpWatchthis' ) ) {
  243. $data['wpWatchthis'] = true;
  244. }
  245. $request = new FauxRequest( $data, true );
  246. // Find existing article if it exists,
  247. // or create a new one.
  248. $article = new Article( $target_title, 0 );
  249. $editor = new EditPage( $article );
  250. $editor->importFormData( $request );
  251. // Try to save the page!
  252. $resultDetails = array();
  253. $saveResult = $editor->internalAttemptSave( $resultDetails );
  254. // Return value was made an object in MW 1.19
  255. if ( is_object( $saveResult ) ) {
  256. $saveResultCode = $saveResult->value;
  257. } else {
  258. $saveResultCode = $saveResult;
  259. }
  260. if ( ( $saveResultCode == EditPage::AS_HOOK_ERROR || $saveResultCode == EditPage::AS_HOOK_ERROR_EXPECTED ) && $redirectOnError ) {
  261. $wgOut->clearHTML();
  262. $wgOut->setArticleBodyOnly(true);
  263. // Lets other code process additional form-definition syntax
  264. wfRunHooks( 'sfWritePageData', array( $form_name, $target_title, &$data_text ) );
  265. $text = SFUtils::printRedirectForm( $target_title, $data_text, $wgRequest->getVal( 'wpSummary' ), $save_page, $preview_page, $diff_page, $wgRequest->getCheck( 'wpMinoredit' ), $wgRequest->getCheck( 'wpWatchthis' ), $wgRequest->getVal( 'wpStarttime' ), $wgRequest->getVal( 'wpEdittime' ) );
  266. } else {
  267. if ( $saveResultCode == EditPage::AS_SUCCESS_UPDATE || $saveResultCode == EditPage::AS_SUCCESS_NEW_ARTICLE ) {
  268. $wgOut->redirect( $target_title->getFullURL() );
  269. }
  270. return SFUtils::processEditErrors( $saveResultCode );
  271. }
  272. } else {
  273. // Lets other code process additional form-definition syntax
  274. wfRunHooks( 'sfWritePageData', array( $form_name, $target_title, &$data_text ) );
  275. $text = SFUtils::printRedirectForm( $target_title, $data_text, $wgRequest->getVal( 'wpSummary' ), $save_page, $preview_page, $diff_page, $wgRequest->getCheck( 'wpMinoredit' ), $wgRequest->getCheck( 'wpWatchthis' ), $wgRequest->getVal( 'wpStarttime' ), $wgRequest->getVal( 'wpEdittime' ) ); // extract its data
  276. }
  277. } else {
  278. // override the default title for this page if
  279. // a title was specified in the form
  280. if ( $form_page_title != null ) {
  281. if ( $target_name == '' ) {
  282. $wgOut->setPageTitle( $form_page_title );
  283. } else {
  284. $wgOut->setPageTitle( "$form_page_title: {$target_title->getPrefixedText()}" );
  285. }
  286. }
  287. $text = "";
  288. if ( count( $alt_forms ) > 0 ) {
  289. $text .= '<div class="infoMessage">' . wfMsg( 'sf_formedit_altforms' ) . ' ';
  290. $text .= self::printAltFormsList( $alt_forms, $target_name );
  291. $text .= "</div>\n";
  292. }
  293. $text .= <<<END
  294. <form name="createbox" id="sfForm" action="" method="post" class="createbox">
  295. END;
  296. $pre_form_html = '';
  297. wfRunHooks( 'sfHTMLBeforeForm', array( &$target_title, &$pre_form_html ) );
  298. $text .= $pre_form_html;
  299. $text .= $form_text;
  300. }
  301. }
  302. SFUtils::addJavascriptAndCSS();
  303. if ( ! empty( $javascript_text ) ) {
  304. $wgOut->addScript( ' <script type="text/javascript">' . "\n$javascript_text\n" . '</script>' . "\n" );
  305. }
  306. $wgOut->addHTML( $text );
  307. return null;
  308. }
  309. }