Merge "registration: Only allow one extension to set a specific config setting"
[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 return $context;
77 }
78
79 /**
80 * If we are trying to edit and no token is set, supply one.
81 *
82 * @param DerivativeContext $context
83 */
84 private function setEditTokenFromUser( DerivativeContext $context ) {
85 $request = $context->getRequest();
86
87 // Edits via GET are a security issue and should not succeed. On the other hand, not all
88 // POST requests are edits, but should ignore unused parameters.
89 if ( !$request->getCheck( 'wpEditToken' ) && $request->wasPosted() ) {
90 $request->setVal( 'wpEditToken', $context->getUser()->getEditToken() );
91 }
92 }
93
94 /**
95 * @param SpecialPage $page
96 * @param string $subPage
97 *
98 * @throws Exception
99 * @return string HTML
100 */
101 private function getHTMLFromSpecialPage( SpecialPage $page, $subPage ) {
102 ob_start();
103
104 try {
105 $page->execute( $subPage );
106
107 $output = $page->getOutput();
108
109 if ( $output->getRedirect() !== '' ) {
110 $output->output();
111 $html = ob_get_contents();
112 } elseif ( $output->isDisabled() ) {
113 $html = ob_get_contents();
114 } else {
115 $html = $output->getHTML();
116 }
117 } catch ( Exception $ex ) {
118 ob_end_clean();
119
120 // Re-throw exception after "finally" handling because PHP 5.3 doesn't have "finally".
121 throw $ex;
122 }
123
124 ob_end_clean();
125
126 return $html;
127 }
128
129 }