]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/import/ImportStreamSource.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / import / ImportStreamSource.php
1 <?php
2 /**
3  * MediaWiki page data importer.
4  *
5  * Copyright © 2003,2005 Brion Vibber <brion@pobox.com>
6  * https://www.mediawiki.org/
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  * http://www.gnu.org/copyleft/gpl.html
22  *
23  * @file
24  * @ingroup SpecialPage
25  */
26 use MediaWiki\MediaWikiServices;
27
28 /**
29  * Imports a XML dump from a file (either from file upload, files on disk, or HTTP)
30  * @ingroup SpecialPage
31  */
32 class ImportStreamSource implements ImportSource {
33         function __construct( $handle ) {
34                 $this->mHandle = $handle;
35         }
36
37         /**
38          * @return bool
39          */
40         function atEnd() {
41                 return feof( $this->mHandle );
42         }
43
44         /**
45          * @return string
46          */
47         function readChunk() {
48                 return fread( $this->mHandle, 32768 );
49         }
50
51         /**
52          * @param string $filename
53          * @return Status
54          */
55         static function newFromFile( $filename ) {
56                 MediaWiki\suppressWarnings();
57                 $file = fopen( $filename, 'rt' );
58                 MediaWiki\restoreWarnings();
59                 if ( !$file ) {
60                         return Status::newFatal( "importcantopen" );
61                 }
62                 return Status::newGood( new ImportStreamSource( $file ) );
63         }
64
65         /**
66          * @param string $fieldname
67          * @return Status
68          */
69         static function newFromUpload( $fieldname = "xmlimport" ) {
70                 $upload =& $_FILES[$fieldname];
71
72                 if ( $upload === null || !$upload['name'] ) {
73                         return Status::newFatal( 'importnofile' );
74                 }
75                 if ( !empty( $upload['error'] ) ) {
76                         switch ( $upload['error'] ) {
77                                 case 1:
78                                         # The uploaded file exceeds the upload_max_filesize directive in php.ini.
79                                         return Status::newFatal( 'importuploaderrorsize' );
80                                 case 2:
81                                         # The uploaded file exceeds the MAX_FILE_SIZE directive that
82                                         # was specified in the HTML form.
83                                         return Status::newFatal( 'importuploaderrorsize' );
84                                 case 3:
85                                         # The uploaded file was only partially uploaded
86                                         return Status::newFatal( 'importuploaderrorpartial' );
87                                 case 6:
88                                         # Missing a temporary folder.
89                                         return Status::newFatal( 'importuploaderrortemp' );
90                                 # case else: # Currently impossible
91                         }
92
93                 }
94                 $fname = $upload['tmp_name'];
95                 if ( is_uploaded_file( $fname ) ) {
96                         return self::newFromFile( $fname );
97                 } else {
98                         return Status::newFatal( 'importnofile' );
99                 }
100         }
101
102         /**
103          * @param string $url
104          * @param string $method
105          * @return Status
106          */
107         static function newFromURL( $url, $method = 'GET' ) {
108                 global $wgHTTPImportTimeout;
109                 wfDebug( __METHOD__ . ": opening $url\n" );
110                 # Use the standard HTTP fetch function; it times out
111                 # quicker and sorts out user-agent problems which might
112                 # otherwise prevent importing from large sites, such
113                 # as the Wikimedia cluster, etc.
114                 $data = Http::request(
115                         $method,
116                         $url,
117                         [
118                                 'followRedirects' => true,
119                                 'timeout' => $wgHTTPImportTimeout
120                         ],
121                         __METHOD__
122                 );
123                 if ( $data !== false ) {
124                         $file = tmpfile();
125                         fwrite( $file, $data );
126                         fflush( $file );
127                         fseek( $file, 0 );
128                         return Status::newGood( new ImportStreamSource( $file ) );
129                 } else {
130                         return Status::newFatal( 'importcantopen' );
131                 }
132         }
133
134         /**
135          * @param string $interwiki
136          * @param string $page
137          * @param bool $history
138          * @param bool $templates
139          * @param int $pageLinkDepth
140          * @return Status
141          */
142         public static function newFromInterwiki( $interwiki, $page, $history = false,
143                 $templates = false, $pageLinkDepth = 0
144         ) {
145                 if ( $page == '' ) {
146                         return Status::newFatal( 'import-noarticle' );
147                 }
148
149                 # Look up the first interwiki prefix, and let the foreign site handle
150                 # subsequent interwiki prefixes
151                 $firstIwPrefix = strtok( $interwiki, ':' );
152                 $interwikiLookup = MediaWikiServices::getInstance()->getInterwikiLookup();
153                 $firstIw = $interwikiLookup->fetch( $firstIwPrefix );
154                 if ( !$firstIw ) {
155                         return Status::newFatal( 'importbadinterwiki' );
156                 }
157
158                 $additionalIwPrefixes = strtok( '' );
159                 if ( $additionalIwPrefixes ) {
160                         $additionalIwPrefixes .= ':';
161                 }
162                 # Have to do a DB-key replacement ourselves; otherwise spaces get
163                 # URL-encoded to +, which is wrong in this case. Similar to logic in
164                 # Title::getLocalURL
165                 $link = $firstIw->getURL( strtr( "${additionalIwPrefixes}Special:Export/$page",
166                         ' ', '_' ) );
167
168                 $params = [];
169                 if ( $history ) {
170                         $params['history'] = 1;
171                 }
172                 if ( $templates ) {
173                         $params['templates'] = 1;
174                 }
175                 if ( $pageLinkDepth ) {
176                         $params['pagelink-depth'] = $pageLinkDepth;
177                 }
178
179                 $url = wfAppendQuery( $link, $params );
180                 # For interwikis, use POST to avoid redirects.
181                 return self::newFromURL( $url, "POST" );
182         }
183 }