Merge "mw.ui: button: Update focus state"
[lhc/web/wiklou.git] / includes / libs / virtualrest / RestbaseVirtualRESTService.php
1 <?php
2 /**
3 * Virtual HTTP service client for Restbase
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 */
20
21 /**
22 * Virtual REST service for Restbase
23 * @since 1.25
24 */
25 class RestbaseVirtualRESTService extends VirtualRESTService {
26 /**
27 * Example requests:
28 * GET /local/v1/page/{title}/html{/revision}
29 * POST /local/v1/transform/html/to/wikitext{/title}{/revision}
30 * * body: array( 'html' => ... )
31 * POST /local/v1/transform/wikitext/to/html{/title}{/revision}
32 * * body: array( 'wikitext' => ... ) or array( 'wikitext' => ..., 'bodyOnly' => true/false )
33 *
34 * @param array $params Key/value map
35 * - url : Restbase server URL
36 * - domain : Wiki domain to use
37 * - timeout : request timeout in seconds (optional)
38 * - forwardCookies : cookies to forward to Restbase/Parsoid (as a Cookie
39 * header string) or false (optional)
40 * Note: forwardCookies will in the future be a boolean
41 * only, signifing request cookies should be forwarded
42 * to the service; the current state is due to the way
43 * VE handles this particular parameter
44 * - HTTPProxy : HTTP proxy to use (optional)
45 * - parsoidCompat : whether to parse URL as if they were meant for Parsoid
46 * boolean (optional)
47 */
48 public function __construct( array $params ) {
49 // set up defaults and merge them with the given params
50 $mparams = array_merge( array(
51 'url' => 'http://localhost:7231',
52 'domain' => 'localhost',
53 'timeout' => 100,
54 'forwardCookies' => false,
55 'HTTPProxy' => null,
56 'parsoidCompat' => false
57 ), $params );
58 // ensure the correct domain format
59 $mparams['domain'] = preg_replace(
60 '/^(https?:\/\/)?([^\/:]+?)(\/|:\d+\/?)?$/',
61 '$2',
62 $mparams['domain']
63 );
64 parent::__construct( $mparams );
65 }
66
67 public function onRequests( array $reqs, Closure $idGenFunc ) {
68
69 if ( $this->params['parsoidCompat'] ) {
70 return $this->onParsoidRequests( $reqs, $idGenFunc );
71 }
72
73 $result = array();
74 foreach ( $reqs as $key => $req ) {
75 // replace /local/ with the current domain
76 $req['url'] = preg_replace( '/^\/local\//', '/' . $this->params['domain'] . '/', $req['url'] );
77 // and prefix it with the service URL
78 $req['url'] = $this->params['url'] . $req['url'];
79 // set the appropriate proxy, timeout and headers
80 if ( $this->params['HTTPProxy'] ) {
81 $req['proxy'] = $this->params['HTTPProxy'];
82 }
83 if ( $this->params['timeout'] != null ) {
84 $req['reqTimeout'] = $this->params['timeout'];
85 }
86 if ( $this->params['forwardCookies'] ) {
87 $req['headers']['Cookie'] = $this->params['forwardCookies'];
88 }
89 $result[$key] = $req;
90 }
91
92 return $result;
93
94 }
95
96 /**
97 * Remaps Parsoid requests to Restbase paths
98 */
99 public function onParsoidRequests( array $reqs, Closure $idGeneratorFunc ) {
100
101 $result = array();
102 foreach ( $reqs as $key => $req ) {
103 $parts = explode( '/', $req['url'] );
104 list(
105 $targetWiki, // 'local'
106 $version, // 'v1'
107 $reqType // 'page' or 'transform'
108 ) = $parts;
109 if ( $targetWiki !== 'local' ) {
110 throw new Exception( "Only 'local' target wiki is currently supported" );
111 } elseif ( $reqType !== 'page' && $reqType !== 'transform' ) {
112 throw new Exception( "Request type must be either 'page' or 'transform'" );
113 }
114 $req['url'] = $this->params['url'] . '/' . $this->params['domain'] . '/v1/' . $reqType . '/';
115 if ( $reqType === 'page' ) {
116 $title = $parts[3];
117 if ( $parts[4] !== 'html' ) {
118 throw new Exception( "Only 'html' output format is currently supported" );
119 }
120 $req['url'] .= 'html/' . $title;
121 if ( isset( $parts[5] ) ) {
122 $req['url'] .= '/' . $parts[5];
123 } elseif ( isset( $req['query']['oldid'] ) && $req['query']['oldid'] ) {
124 $req['url'] .= '/' . $req['query']['oldid'];
125 unset( $req['query']['oldid'] );
126 }
127 } elseif ( $reqType === 'transform' ) {
128 // from / to transform
129 $req['url'] .= $parts[3] . '/to/' . $parts[5];
130 // the title
131 if ( isset( $parts[6] ) ) {
132 $req['url'] .= '/' . $parts[6];
133 }
134 // revision id
135 if ( isset( $parts[7] ) ) {
136 $req['url'] .= '/' . $parts[7];
137 } elseif ( isset( $req['body']['oldid'] ) && $req['body']['oldid'] ) {
138 $req['url'] .= '/' . $req['body']['oldid'];
139 unset( $req['body']['oldid'] );
140 }
141 if ( $parts[4] !== 'to' ) {
142 throw new Exception( "Part index 4 is not 'to'" );
143 }
144 if ( $parts[3] === 'html' & $parts[5] === 'wikitext' ) {
145 if ( !isset( $req['body']['html'] ) ) {
146 throw new Exception( "You must set an 'html' body key for this request" );
147 }
148 } elseif ( $parts[3] == 'wikitext' && $parts[5] == 'html' ) {
149 if ( !isset( $req['body']['wikitext'] ) ) {
150 throw new Exception( "You must set a 'wikitext' body key for this request" );
151 }
152 if ( isset( $req['body']['body'] ) ) {
153 $req['body']['bodyOnly'] = $req['body']['body'];
154 unset( $req['body']['body'] );
155 }
156 } else {
157 throw new Exception( "Transformation unsupported" );
158 }
159 }
160 // set the appropriate proxy, timeout and headers
161 if ( $this->params['HTTPProxy'] ) {
162 $req['proxy'] = $this->params['HTTPProxy'];
163 }
164 if ( $this->params['timeout'] != null ) {
165 $req['reqTimeout'] = $this->params['timeout'];
166 }
167 if ( $this->params['forwardCookies'] ) {
168 $req['headers']['Cookie'] = $this->params['forwardCookies'];
169 }
170 $result[$key] = $req;
171 }
172
173 return $result;
174
175 }
176
177 }