Merge "Drop cache interwiki"
[mediawiki.git] / tests / phpunit / includes / specials / SpecialPageExecutor.php
blob74a36915adf46a8fe5b46c0cba3f0fb7fd06bfa7
1 <?php
3 use MediaWiki\Context\DerivativeContext;
4 use MediaWiki\Context\RequestContext;
5 use MediaWiki\Language\Language;
6 use MediaWiki\Output\OutputPage;
7 use MediaWiki\Permissions\Authority;
8 use MediaWiki\Request\FauxRequest;
9 use MediaWiki\Request\FauxResponse;
10 use MediaWiki\Request\WebRequest;
11 use MediaWiki\SpecialPage\SpecialPage;
13 /**
14 * @author Addshore
16 * @since 1.27
18 class SpecialPageExecutor {
20 /**
21 * @param SpecialPage $page The special page to execute
22 * @param string|null $subPage The subpage parameter to call the page with
23 * @param WebRequest|null $request Web request that may contain URL parameters, etc
24 * @param Language|string|null $language The language which should be used in the context;
25 * if not specified, the pseudo-code 'qqx' is used
26 * @param Authority|null $performer The user which should be used in the context of this special page
27 * @param bool $fullHtml if true, the entirety of the generated HTML will be returned, this
28 * includes the opening <!DOCTYPE> declaration and closing </html> tag. If false, only value
29 * of OutputPage::getHTML() will be returned except if the page is redirect or where OutputPage
30 * is completely disabled.
32 * @return array [ string, WebResponse ] A two-elements array containing the HTML output
33 * generated by the special page as well as the response object.
35 public function executeSpecialPage(
36 SpecialPage $page,
37 $subPage = '',
38 ?WebRequest $request = null,
39 $language = null,
40 ?Authority $performer = null,
41 $fullHtml = false
42 ) {
43 $context = $this->newContext( $request, $language, $performer );
45 $output = new OutputPage( $context );
46 $context->setOutput( $output );
48 $page->setContext( $context );
49 $output->setTitle( $page->getPageTitle() );
51 $html = $this->getHTMLFromSpecialPage( $page, $subPage, $fullHtml );
52 $response = $context->getRequest()->response();
54 if ( $response instanceof FauxResponse ) {
55 $code = $response->getStatusCode();
57 if ( $code > 0 ) {
58 $response->header( 'Status: ' . $code . ' ' . HttpStatus::getMessage( $code ) );
62 return [ $html, $response ];
65 /**
66 * @param WebRequest|null $request
67 * @param Language|string|null $language Defaults to 'qqx'
68 * @param Authority|null $performer
70 * @return DerivativeContext
72 private function newContext(
73 ?WebRequest $request = null,
74 $language = null,
75 ?Authority $performer = null
76 ) {
77 $context = new DerivativeContext( RequestContext::getMain() );
79 $context->setRequest( $request ?: new FauxRequest() );
81 $context->setLanguage( $language ?: 'qqx' );
83 if ( $performer !== null ) {
84 $context->setAuthority( $performer );
87 $this->setEditTokenFromUser( $context );
89 // Make sure the skin context is correctly set https://phabricator.wikimedia.org/T200771
90 $context->getSkin()->setContext( $context );
92 return $context;
95 /**
96 * If we are trying to edit and no token is set, supply one.
98 * @param DerivativeContext $context
100 private function setEditTokenFromUser( DerivativeContext $context ) {
101 $request = $context->getRequest();
103 // Edits via GET are a security issue and should not succeed. On the other hand, not all
104 // POST requests are edits, but should ignore unused parameters.
105 if ( !$request->getCheck( 'wpEditToken' ) && $request->wasPosted() ) {
106 $request->setVal( 'wpEditToken', $context->getUser()->getEditToken() );
111 * @param SpecialPage $page
112 * @param string|null $subPage
113 * @param bool $fullHtml
115 * @return string HTML
117 private function getHTMLFromSpecialPage( SpecialPage $page, $subPage, $fullHtml ) {
118 ob_start();
120 try {
121 $page->execute( $subPage );
123 $output = $page->getOutput();
125 if ( $output->getRedirect() !== '' ) {
126 $output->output();
127 $html = ob_get_contents();
128 } elseif ( $output->isDisabled() ) {
129 $html = ob_get_contents();
130 } elseif ( $fullHtml ) {
131 $html = $output->output( true );
132 } else {
133 $html = $output->getHTML();
135 } finally {
136 ob_end_clean();
139 return $html;