PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/Push/includes/Push_Tab.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 441 lines | 302 code | 55 blank | 84 comment | 25 complexity | d67f8407ed7224c73bf0d627b43b27f7 MD5 | raw file
  1. <?php
  2. /**
  3. * Static class with methods to create and handle the push tab.
  4. *
  5. * @since 0.1
  6. *
  7. * @file Push_Tab.php
  8. * @ingroup Push
  9. *
  10. * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  11. */
  12. final class PushTab {
  13. /**
  14. * Adds an "action" (i.e., a tab) to allow pushing the current article.
  15. */
  16. public static function displayTab( $obj, &$content_actions ) {
  17. global $wgUser, $egPushTargets;
  18. // Make sure that this is not a special page, the page has contents, and the user can push.
  19. $title = $obj->getTitle();
  20. if (
  21. $title->getNamespace() != NS_SPECIAL
  22. && $title->exists()
  23. && $wgUser->isAllowed( 'push' )
  24. && count( $egPushTargets ) > 0 ) {
  25. global $wgRequest;
  26. $content_actions['push'] = array(
  27. 'text' => wfMsg( 'push-tab-text' ),
  28. 'class' => $wgRequest->getVal( 'action' ) == 'push' ? 'selected' : '',
  29. 'href' => $title->getLocalURL( 'action=push' )
  30. );
  31. }
  32. return true;
  33. }
  34. /**
  35. * Function currently called only for the 'Vector' skin, added in
  36. * MW 1.16 - will possibly be called for additional skins later
  37. */
  38. public static function displayTab2( $obj, &$links ) {
  39. global $egPushShowTab;
  40. // The old '$content_actions' array is thankfully just a sub-array of this one
  41. $views_links = $links[$egPushShowTab ? 'views' : 'actions'];
  42. self::displayTab( $obj, $views_links );
  43. $links[$egPushShowTab ? 'views' : 'actions'] = $views_links;
  44. return true;
  45. }
  46. /**
  47. * Handle actions not known to MediaWiki. If the action is push,
  48. * display the push page by calling the displayPushPage method.
  49. *
  50. * @param string $action
  51. * @param Article $article
  52. *
  53. * @return true
  54. */
  55. public static function onUnknownAction( $action, Article $article ) {
  56. if ( $action == 'push' ) {
  57. return self::displayPushPage( $article );
  58. }
  59. else {
  60. return true;
  61. }
  62. }
  63. /**
  64. * Loads the needed JavaScript.
  65. * Takes care of non-RL compatibility.
  66. *
  67. * @since 0.1
  68. */
  69. protected static function loadJs() {
  70. global $wgOut;
  71. // For backward compatibility with MW < 1.17.
  72. if ( is_callable( array( $wgOut, 'addModules' ) ) ) {
  73. $wgOut->addModules( 'ext.push.tab' );
  74. }
  75. else {
  76. global $egPushScriptPath;
  77. PushFunctions::addJSLocalisation();
  78. $wgOut->includeJQuery();
  79. $wgOut->addHeadItem(
  80. 'ext.push.tab',
  81. Html::linkedScript( $egPushScriptPath . '/includes/ext.push.tab.js' )
  82. );
  83. }
  84. }
  85. /**
  86. * The function called if we're in index.php (as opposed to one of the
  87. * special pages)
  88. *
  89. * @since 0.1
  90. */
  91. public static function displayPushPage( Article $article ) {
  92. global $wgOut, $wgUser, $wgTitle, $wgSitename, $egPushTargets;
  93. $wgOut->setPageTitle( wfMsgExt( 'push-tab-title', 'parsemag', $article->getTitle()->getText() ) );
  94. if ( !$wgUser->isAllowed( 'push' ) ) {
  95. $wgOut->permissionRequired( 'push' );
  96. return false;
  97. }
  98. $wgOut->addHTML( '<p>' . htmlspecialchars( wfMsg( 'push-tab-desc' ) ) . '</p>' );
  99. if ( count( $egPushTargets ) == 0 ) {
  100. $wgOut->addHTML( '<p>' . htmlspecialchars( wfMsg( 'push-tab-no-targets' ) ) . '</p>' );
  101. return false;
  102. }
  103. self::loadJs();
  104. $wgOut->addHTML(
  105. Html::hidden( 'pageName', $wgTitle->getFullText(), array( 'id' => 'pageName' ) ) .
  106. Html::hidden( 'siteName', $wgSitename, array( 'id' => 'siteName' ) )
  107. );
  108. self::displayPushList();
  109. self::displayPushOptions();
  110. return false;
  111. }
  112. /**
  113. * Displays a list with all targets to which can be pushed.
  114. *
  115. * @since 0.1
  116. */
  117. protected static function displayPushList() {
  118. global $wgOut, $egPushTargets, $wgLang;
  119. $items = array(
  120. Html::rawElement(
  121. 'tr',
  122. array(),
  123. Html::element(
  124. 'th',
  125. array( 'width' => '200px' ),
  126. wfMsg( 'push-targets' )
  127. ) .
  128. Html::element(
  129. 'th',
  130. array( 'style' => 'min-width:400px;' ),
  131. wfMsg( 'push-remote-pages' )
  132. ) .
  133. Html::element(
  134. 'th',
  135. array( 'width' => '125px' ),
  136. ''
  137. )
  138. )
  139. );
  140. foreach ( $egPushTargets as $name => $url ) {
  141. $items[] = self::getPushItem( $name, $url );
  142. }
  143. // If there is more then one item, display the 'push all' row.
  144. if ( count( $egPushTargets ) > 1 ) {
  145. $items[] = Html::rawElement(
  146. 'tr',
  147. array(),
  148. Html::element(
  149. 'th',
  150. array( 'colspan' => 2, 'style' => 'text-align: left' ),
  151. wfMsgExt( 'push-targets-total', 'parsemag', $wgLang->formatNum( count( $egPushTargets ) ) )
  152. ) .
  153. Html::rawElement(
  154. 'th',
  155. array( 'width' => '125px' ),
  156. Html::element(
  157. 'button',
  158. array(
  159. 'id' => 'push-all-button',
  160. 'style' => 'width: 125px; height: 30px',
  161. ),
  162. wfMsg( 'push-button-all' )
  163. )
  164. )
  165. );
  166. }
  167. $wgOut->addHtml(
  168. Html::rawElement(
  169. 'table',
  170. array( 'class' => 'wikitable', 'width' => '50%' ),
  171. implode( "\n", $items )
  172. )
  173. );
  174. }
  175. /**
  176. * Returns the HTML for a single push target.
  177. *
  178. * @since 0.1
  179. *
  180. * @param string $name
  181. * @param string $url
  182. *
  183. * @return string
  184. */
  185. protected static function getPushItem( $name, $url ) {
  186. global $wgTitle;
  187. static $targetId = 0;
  188. $targetId++;
  189. return Html::rawElement(
  190. 'tr',
  191. array(),
  192. Html::element(
  193. 'td',
  194. array(),
  195. $name
  196. ) .
  197. Html::rawElement(
  198. 'td',
  199. array( 'height' => '45px' ),
  200. Html::element(
  201. 'a',
  202. array(
  203. 'href' => $url . '/index.php?title=' . $wgTitle->getFullText(),
  204. 'rel' => 'nofollow',
  205. 'id' => 'targetlink' . $targetId
  206. ),
  207. wfMsgExt( 'push-remote-page-link', 'parsemag', $wgTitle->getFullText(), $name )
  208. ) .
  209. Html::element(
  210. 'div',
  211. array(
  212. 'id' => 'targetinfo' . $targetId,
  213. 'style' => 'display:none; color:darkgray'
  214. )
  215. ) .
  216. Html::element(
  217. 'div',
  218. array(
  219. 'id' => 'targettemplateconflicts' . $targetId,
  220. 'style' => 'display:none; color:darkgray'
  221. )
  222. ) .
  223. Html::element(
  224. 'div',
  225. array(
  226. 'id' => 'targetfileconflicts' . $targetId,
  227. 'style' => 'display:none; color:darkgray'
  228. )
  229. ) .
  230. Html::element(
  231. 'div',
  232. array(
  233. 'id' => 'targeterrors' . $targetId,
  234. 'style' => 'display:none; color:darkred'
  235. )
  236. )
  237. ) .
  238. Html::rawElement(
  239. 'td',
  240. array(),
  241. Html::element(
  242. 'button',
  243. array(
  244. 'class' => 'push-button',
  245. 'pushtarget' => $url,
  246. 'style' => 'width: 125px; height: 30px',
  247. 'targetid' => $targetId,
  248. 'targetname' => $name
  249. ),
  250. wfMsg( 'push-button-text' )
  251. )
  252. )
  253. );
  254. }
  255. /**
  256. * Outputs the HTML for the push options.
  257. *
  258. * @since 0.4
  259. */
  260. protected static function displayPushOptions() {
  261. global $wgOut, $wgUser, $wgTitle;
  262. $wgOut->addHTML( '<h3>' . htmlspecialchars( wfMsg( 'push-tab-push-options' ) ) . '</h3>' );
  263. $usedTemplates = array_keys(
  264. PushFunctions::getTemplates(
  265. array( $wgTitle->getFullText() ),
  266. array( $wgTitle->getFullText() => true )
  267. )
  268. );
  269. // Get rid of the page itself.
  270. array_shift( $usedTemplates );
  271. self::displayIncTemplatesOption( $usedTemplates );
  272. if ( $wgUser->isAllowed( 'filepush' ) ) {
  273. self::displayIncFilesOption( $usedTemplates );
  274. }
  275. }
  276. /**
  277. * Outputs the HTML for the "include templates" option.
  278. *
  279. * @since 0.4
  280. *
  281. * @param array $templates
  282. */
  283. protected static function displayIncTemplatesOption( array $templates ) {
  284. global $wgOut, $wgLang, $egPushIncTemplates;
  285. $wgOut->addInlineScript(
  286. 'var wgPushTemplates = ' . FormatJson::encode( $templates ) . ';'
  287. );
  288. foreach ( $templates as &$template ) {
  289. $template = "[[$template]]";
  290. }
  291. $wgOut->addHTML(
  292. Html::rawElement(
  293. 'div',
  294. array( 'id' => 'divIncTemplates', 'style' => 'display: table-row' ),
  295. Xml::check( 'checkIncTemplates', $egPushIncTemplates, array( 'id' => 'checkIncTemplates' ) ) .
  296. Html::element(
  297. 'label',
  298. array( 'id' => 'lblIncTemplates', 'for' => 'checkIncTemplates' ),
  299. wfMsg( 'push-tab-inc-templates' )
  300. ) .
  301. '&#160;' .
  302. Html::rawElement(
  303. 'div',
  304. array( 'style' => 'display:none; opacity:0', 'id' => 'txtTemplateList' ),
  305. count( $templates ) > 0 ?
  306. wfMsgExt( 'push-tab-used-templates', 'parseinline', $wgLang->listToText( $templates ), count( $templates ) ) :
  307. htmlspecialchars( wfMsg( 'push-tab-no-used-templates' ) )
  308. )
  309. )
  310. );
  311. }
  312. /**
  313. * Outputs the HTML for the "include files" option.
  314. *
  315. * @since 0.4
  316. *
  317. * @param array $templates
  318. */
  319. protected static function displayIncFilesOption( array $templates ) {
  320. global $wgOut, $wgTitle, $egPushIncFiles, $wgScript;
  321. $allFiles = self::getImagesForPages( array( $wgTitle->getFullText() ) );
  322. $templateFiles = self::getImagesForPages( $templates );
  323. $pageFiles = array();
  324. foreach ( $allFiles as $file ) {
  325. if ( !in_array( $file, $templateFiles ) ) {
  326. $pageFiles[] = $file;
  327. }
  328. }
  329. $wgOut->addInlineScript(
  330. 'var wgPushPageFiles = ' . FormatJson::encode( $pageFiles ) . ';' .
  331. 'var wgPushTemplateFiles = ' . FormatJson::encode( $templateFiles ) . ';' .
  332. 'var wgPushIndexPath = ' . FormatJson::encode( $wgScript )
  333. );
  334. $wgOut->addHTML(
  335. Html::rawElement(
  336. 'div',
  337. array( 'id' => 'divIncFiles', 'style' => 'display: table-row' ),
  338. Xml::check( 'checkIncFiles', $egPushIncFiles, array( 'id' => 'checkIncFiles' ) ) .
  339. Html::element(
  340. 'label',
  341. array( 'id' => 'lblIncFiles', 'for' => 'checkIncFiles' ),
  342. wfMsg( 'push-tab-inc-files' )
  343. ) .
  344. '&#160;' .
  345. Html::rawElement(
  346. 'div',
  347. array( 'style' => 'display:none; opacity:0', 'id' => 'txtFileList' ),
  348. ''
  349. )
  350. )
  351. );
  352. }
  353. /**
  354. * Returns the names of the images embedded in a set of pages.
  355. *
  356. * @param array $pages
  357. *
  358. * @return array
  359. */
  360. protected static function getImagesForPages( array $pages ) {
  361. $images = array();
  362. $requestData = array(
  363. 'action' => 'query',
  364. 'format' => 'json',
  365. 'prop' => 'images',
  366. 'titles' => implode( '|', $pages ),
  367. 'imlimit' => 500
  368. );
  369. $api = new ApiMain( new FauxRequest( $requestData, true ), true );
  370. $api->execute();
  371. $response = $api->getResultData();
  372. if ( is_array( $response ) && array_key_exists( 'query', $response ) && array_key_exists( 'pages', $response['query'] ) ) {
  373. foreach ( $response['query']['pages'] as $page ) {
  374. if ( array_key_exists( 'images', $page ) ) {
  375. foreach ( $page['images'] as $image ) {
  376. $title = Title::newFromText( $image['title'], NS_FILE );
  377. if ( !is_null( $title ) && $title->getNamespace() == NS_FILE && $title->exists() ) {
  378. $images[] = $image['title'];
  379. }
  380. }
  381. }
  382. }
  383. }
  384. return array_unique( $images );
  385. }
  386. }