Do not insert page titles into querycache.qc_value
[lhc/web/wiklou.git] / tests / phpunit / includes / specials / SpecialPageExecutor.php
1 <?php
2
3 /**
4 * @author Addshore
5 *
6 * @since 1.27
7 */
8 class SpecialPageExecutor {
9
10 /**
11 * @param SpecialPage $page The special page to execute
12 * @param string $subPage The subpage parameter to call the page with
13 * @param WebRequest|null $request Web request that may contain URL parameters, etc
14 * @param Language|string|null $language The language which should be used in the context
15 * @param User|null $user The user which should be used in the context of this special page
16 *
17 * @throws Exception
18 * @return array [ string, WebResponse ] A two-elements array containing the HTML output
19 * generated by the special page as well as the response object.
20 */
21 public function executeSpecialPage(
22 SpecialPage $page,
23 $subPage = '',
24 WebRequest $request = null,
25 $language = null,
26 User $user = null
27 ) {
28 $context = $this->newContext( $request, $language, $user );
29
30 $output = new OutputPage( $context );
31 $context->setOutput( $output );
32
33 $page->setContext( $context );
34 $output->setTitle( $page->getPageTitle() );
35
36 $html = $this->getHTMLFromSpecialPage( $page, $subPage );
37 $response = $context->getRequest()->response();
38
39 if ( $response instanceof FauxResponse ) {
40 $code = $response->getStatusCode();
41
42 if ( $code > 0 ) {
43 $response->header( 'Status: ' . $code . ' ' . HttpStatus::getMessage( $code ) );
44 }
45 }
46
47 return [ $html, $response ];
48 }
49
50 /**
51 * @param WebRequest|null $request
52 * @param Language|string|null $language
53 * @param User|null $user
54 *
55 * @return DerivativeContext
56 */
57 private function newContext(
58 WebRequest $request = null,
59 $language = null,
60 User $user = null
61 ) {
62 $context = new DerivativeContext( RequestContext::getMain() );
63
64 $context->setRequest( $request ?: new FauxRequest() );
65
66 if ( $language !== null ) {
67 $context->setLanguage( $language );
68 }
69
70 if ( $user !== null ) {
71 $context->setUser( $user );
72 }
73
74 $this->setEditTokenFromUser( $context );
75
76 // Make sure the skin context is correctly set https://phabricator.wikimedia.org/T200771
77 $context->getSkin()->setContext( $context );
78
79 return $context;
80 }
81
82 /**
83 * If we are trying to edit and no token is set, supply one.
84 *
85 * @param DerivativeContext $context
86 */
87 private function setEditTokenFromUser( DerivativeContext $context ) {
88 $request = $context->getRequest();
89
90 // Edits via GET are a security issue and should not succeed. On the other hand, not all
91 // POST requests are edits, but should ignore unused parameters.
92 if ( !$request->getCheck( 'wpEditToken' ) && $request->wasPosted() ) {
93 $request->setVal( 'wpEditToken', $context->getUser()->getEditToken() );
94 }
95 }
96
97 /**
98 * @param SpecialPage $page
99 * @param string $subPage
100 *
101 * @throws Exception
102 * @return string HTML
103 */
104 private function getHTMLFromSpecialPage( SpecialPage $page, $subPage ) {
105 ob_start();
106
107 try {
108 $page->execute( $subPage );
109
110 $output = $page->getOutput();
111
112 if ( $output->getRedirect() !== '' ) {
113 $output->output();
114 $html = ob_get_contents();
115 } elseif ( $output->isDisabled() ) {
116 $html = ob_get_contents();
117 } else {
118 $html = $output->getHTML();
119 }
120 } finally {
121 ob_end_clean();
122 }
123
124 return $html;
125 }
126
127 }