Enable configuration to supply options for Special:Search form
[lhc/web/wiklou.git] / includes / import / WikiRevision.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\Logger\LoggerFactory;
27 use MediaWiki\MediaWikiServices;
28
29 /**
30 * Represents a revision, log entry or upload during the import process.
31 * This class sticks closely to the structure of the XML dump.
32 *
33 * @since 1.2
34 *
35 * @ingroup SpecialPage
36 */
37 class WikiRevision implements ImportableUploadRevision, ImportableOldRevision {
38
39 /**
40 * @since 1.2
41 * @var Title
42 */
43 public $title = null;
44
45 /**
46 * @since 1.6.4
47 * @var int
48 */
49 public $id = 0;
50
51 /**
52 * @since 1.2
53 * @var string
54 */
55 public $timestamp = "20010115000000";
56
57 /**
58 * @since 1.2
59 * @var int
60 * @deprecated in 1.29. Unused.
61 * @note Introduced in 436a028086fb3f01c4605c5ad2964d56f9306aca, unused there, unused now.
62 */
63 public $user = 0;
64
65 /**
66 * @since 1.2
67 * @var string
68 */
69 public $user_text = "";
70
71 /**
72 * @since 1.27
73 * @var User
74 */
75 public $userObj = null;
76
77 /**
78 * @since 1.21
79 * @var string
80 */
81 public $model = null;
82
83 /**
84 * @since 1.21
85 * @var string
86 */
87 public $format = null;
88
89 /**
90 * @since 1.2
91 * @var string
92 */
93 public $text = "";
94
95 /**
96 * @since 1.12.2
97 * @var int
98 */
99 protected $size;
100
101 /**
102 * @since 1.21
103 * @var Content
104 */
105 public $content = null;
106
107 /**
108 * @since 1.24
109 * @var ContentHandler
110 */
111 protected $contentHandler = null;
112
113 /**
114 * @since 1.2.6
115 * @var string
116 */
117 public $comment = "";
118
119 /**
120 * @since 1.5.7
121 * @var bool
122 */
123 public $minor = false;
124
125 /**
126 * @since 1.12.2
127 * @var string
128 */
129 public $type = "";
130
131 /**
132 * @since 1.12.2
133 * @var string
134 */
135 public $action = "";
136
137 /**
138 * @since 1.12.2
139 * @var string
140 */
141 public $params = "";
142
143 /**
144 * @since 1.17
145 * @var string
146 */
147 public $fileSrc = '';
148
149 /**
150 * @since 1.17
151 * @var bool|string
152 */
153 public $sha1base36 = false;
154
155 /**
156 * @since 1.17
157 * @var string
158 */
159 public $archiveName = '';
160
161 /**
162 * @since 1.12.2
163 */
164 protected $filename;
165
166 /**
167 * @since 1.12.2
168 * @var string|null
169 */
170 protected $src = null;
171
172 /**
173 * @since 1.18
174 * @var bool
175 * @todo Unused?
176 */
177 public $isTemp = false;
178
179 /**
180 * @since 1.18
181 * @deprecated 1.29 use Wikirevision::isTempSrc()
182 * First written to in 43d5d3b682cc1733ad01a837d11af4a402d57e6a
183 * Actually introduced in 52cd34acf590e5be946b7885ffdc13a157c1c6cf
184 */
185 public $fileIsTemp;
186
187 /** @var bool */
188 private $mNoUpdates = false;
189
190 /** @var Config $config */
191 private $config;
192
193 public function __construct( Config $config ) {
194 $this->config = $config;
195 }
196
197 /**
198 * @since 1.7 taking a Title object (string before)
199 * @param Title $title
200 * @throws MWException
201 */
202 public function setTitle( $title ) {
203 if ( is_object( $title ) ) {
204 $this->title = $title;
205 } elseif ( is_null( $title ) ) {
206 throw new MWException( "WikiRevision given a null title in import. "
207 . "You may need to adjust \$wgLegalTitleChars." );
208 } else {
209 throw new MWException( "WikiRevision given non-object title in import." );
210 }
211 }
212
213 /**
214 * @since 1.6.4
215 * @param int $id
216 */
217 public function setID( $id ) {
218 $this->id = $id;
219 }
220
221 /**
222 * @since 1.2
223 * @param string $ts
224 */
225 public function setTimestamp( $ts ) {
226 # 2003-08-05T18:30:02Z
227 $this->timestamp = wfTimestamp( TS_MW, $ts );
228 }
229
230 /**
231 * @since 1.2
232 * @param string $user
233 */
234 public function setUsername( $user ) {
235 $this->user_text = $user;
236 }
237
238 /**
239 * @since 1.27
240 * @param User $user
241 */
242 public function setUserObj( $user ) {
243 $this->userObj = $user;
244 }
245
246 /**
247 * @since 1.2
248 * @param string $ip
249 */
250 public function setUserIP( $ip ) {
251 $this->user_text = $ip;
252 }
253
254 /**
255 * @since 1.21
256 * @param string $model
257 */
258 public function setModel( $model ) {
259 $this->model = $model;
260 }
261
262 /**
263 * @since 1.21
264 * @param string $format
265 */
266 public function setFormat( $format ) {
267 $this->format = $format;
268 }
269
270 /**
271 * @since 1.2
272 * @param string $text
273 */
274 public function setText( $text ) {
275 $this->text = $text;
276 }
277
278 /**
279 * @since 1.2.6
280 * @param string $text
281 */
282 public function setComment( $text ) {
283 $this->comment = $text;
284 }
285
286 /**
287 * @since 1.5.7
288 * @param bool $minor
289 */
290 public function setMinor( $minor ) {
291 $this->minor = (bool)$minor;
292 }
293
294 /**
295 * @since 1.12.2
296 * @param string|null $src
297 */
298 public function setSrc( $src ) {
299 $this->src = $src;
300 }
301
302 /**
303 * @since 1.17
304 * @param string $src
305 * @param bool $isTemp
306 */
307 public function setFileSrc( $src, $isTemp ) {
308 $this->fileSrc = $src;
309 $this->fileIsTemp = $isTemp;
310 $this->isTemp = $isTemp;
311 }
312
313 /**
314 * @since 1.17
315 * @param string $sha1base36
316 */
317 public function setSha1Base36( $sha1base36 ) {
318 $this->sha1base36 = $sha1base36;
319 }
320
321 /**
322 * @since 1.12.2
323 * @param string $filename
324 */
325 public function setFilename( $filename ) {
326 $this->filename = $filename;
327 }
328
329 /**
330 * @since 1.17
331 * @param string $archiveName
332 */
333 public function setArchiveName( $archiveName ) {
334 $this->archiveName = $archiveName;
335 }
336
337 /**
338 * @since 1.12.2
339 * @param int $size
340 */
341 public function setSize( $size ) {
342 $this->size = intval( $size );
343 }
344
345 /**
346 * @since 1.12.2
347 * @param string $type
348 */
349 public function setType( $type ) {
350 $this->type = $type;
351 }
352
353 /**
354 * @since 1.12.2
355 * @param string $action
356 */
357 public function setAction( $action ) {
358 $this->action = $action;
359 }
360
361 /**
362 * @since 1.12.2
363 * @param array $params
364 */
365 public function setParams( $params ) {
366 $this->params = $params;
367 }
368
369 /**
370 * @since 1.18
371 * @param bool $noupdates
372 */
373 public function setNoUpdates( $noupdates ) {
374 $this->mNoUpdates = $noupdates;
375 }
376
377 /**
378 * @since 1.2
379 * @return Title
380 */
381 public function getTitle() {
382 return $this->title;
383 }
384
385 /**
386 * @since 1.6.4
387 * @return int
388 */
389 public function getID() {
390 return $this->id;
391 }
392
393 /**
394 * @since 1.2
395 * @return string
396 */
397 public function getTimestamp() {
398 return $this->timestamp;
399 }
400
401 /**
402 * @since 1.2
403 * @return string
404 */
405 public function getUser() {
406 return $this->user_text;
407 }
408
409 /**
410 * @since 1.27
411 * @return User
412 */
413 public function getUserObj() {
414 return $this->userObj;
415 }
416
417 /**
418 * @since 1.2
419 * @return string
420 */
421 public function getText() {
422 return $this->text;
423 }
424
425 /**
426 * @since 1.24
427 * @return ContentHandler
428 */
429 public function getContentHandler() {
430 if ( is_null( $this->contentHandler ) ) {
431 $this->contentHandler = ContentHandler::getForModelID( $this->getModel() );
432 }
433
434 return $this->contentHandler;
435 }
436
437 /**
438 * @since 1.21
439 * @return Content
440 */
441 public function getContent() {
442 if ( is_null( $this->content ) ) {
443 $handler = $this->getContentHandler();
444 $this->content = $handler->unserializeContent( $this->text, $this->getFormat() );
445 }
446
447 return $this->content;
448 }
449
450 /**
451 * @since 1.21
452 * @return string
453 */
454 public function getModel() {
455 if ( is_null( $this->model ) ) {
456 $this->model = $this->getTitle()->getContentModel();
457 }
458
459 return $this->model;
460 }
461
462 /**
463 * @since 1.21
464 * @return string
465 */
466 public function getFormat() {
467 if ( is_null( $this->format ) ) {
468 $this->format = $this->getContentHandler()->getDefaultFormat();
469 }
470
471 return $this->format;
472 }
473
474 /**
475 * @since 1.2.6
476 * @return string
477 */
478 public function getComment() {
479 return $this->comment;
480 }
481
482 /**
483 * @since 1.5.7
484 * @return bool
485 */
486 public function getMinor() {
487 return $this->minor;
488 }
489
490 /**
491 * @since 1.12.2
492 * @return string|null
493 */
494 public function getSrc() {
495 return $this->src;
496 }
497
498 /**
499 * @since 1.17
500 * @return bool|string
501 */
502 public function getSha1() {
503 if ( $this->sha1base36 ) {
504 return Wikimedia\base_convert( $this->sha1base36, 36, 16 );
505 }
506 return false;
507 }
508
509 /**
510 * @since 1.31
511 * @return bool|string
512 */
513 public function getSha1Base36() {
514 if ( $this->sha1base36 ) {
515 return $this->sha1base36;
516 }
517 return false;
518 }
519
520 /**
521 * @since 1.17
522 * @return string
523 */
524 public function getFileSrc() {
525 return $this->fileSrc;
526 }
527
528 /**
529 * @since 1.17
530 * @return bool
531 */
532 public function isTempSrc() {
533 return $this->isTemp;
534 }
535
536 /**
537 * @since 1.12.2
538 * @return mixed
539 */
540 public function getFilename() {
541 return $this->filename;
542 }
543
544 /**
545 * @since 1.17
546 * @return string
547 */
548 public function getArchiveName() {
549 return $this->archiveName;
550 }
551
552 /**
553 * @since 1.12.2
554 * @return mixed
555 */
556 public function getSize() {
557 return $this->size;
558 }
559
560 /**
561 * @since 1.12.2
562 * @return string
563 */
564 public function getType() {
565 return $this->type;
566 }
567
568 /**
569 * @since 1.12.2
570 * @return string
571 */
572 public function getAction() {
573 return $this->action;
574 }
575
576 /**
577 * @since 1.12.2
578 * @return string
579 */
580 public function getParams() {
581 return $this->params;
582 }
583
584 /**
585 * @since 1.4.1
586 * @deprecated in 1.31. Use OldRevisionImporter::import
587 * @return bool
588 */
589 public function importOldRevision() {
590 if ( $this->mNoUpdates ) {
591 $importer = MediaWikiServices::getInstance()->getWikiRevisionOldRevisionImporterNoUpdates();
592 } else {
593 $importer = MediaWikiServices::getInstance()->getWikiRevisionOldRevisionImporter();
594 }
595 return $importer->import( $this );
596 }
597
598 /**
599 * @since 1.12.2
600 * @return bool
601 */
602 public function importLogItem() {
603 $dbw = wfGetDB( DB_MASTER );
604
605 $user = $this->getUserObj() ?: User::newFromName( $this->getUser(), false );
606
607 # @todo FIXME: This will not record autoblocks
608 if ( !$this->getTitle() ) {
609 wfDebug( __METHOD__ . ": skipping invalid {$this->type}/{$this->action} log time, timestamp " .
610 $this->timestamp . "\n" );
611 return false;
612 }
613 # Check if it exists already
614 // @todo FIXME: Use original log ID (better for backups)
615 $prior = $dbw->selectField( 'logging', '1',
616 [ 'log_type' => $this->getType(),
617 'log_action' => $this->getAction(),
618 'log_timestamp' => $dbw->timestamp( $this->timestamp ),
619 'log_namespace' => $this->getTitle()->getNamespace(),
620 'log_title' => $this->getTitle()->getDBkey(),
621 'log_params' => $this->params ],
622 __METHOD__
623 );
624 // @todo FIXME: This could fail slightly for multiple matches :P
625 if ( $prior ) {
626 wfDebug( __METHOD__
627 . ": skipping existing item for Log:{$this->type}/{$this->action}, timestamp "
628 . $this->timestamp . "\n" );
629 return false;
630 }
631 $data = [
632 'log_type' => $this->type,
633 'log_action' => $this->action,
634 'log_timestamp' => $dbw->timestamp( $this->timestamp ),
635 'log_namespace' => $this->getTitle()->getNamespace(),
636 'log_title' => $this->getTitle()->getDBkey(),
637 'log_params' => $this->params
638 ] + CommentStore::getStore()->insert( $dbw, 'log_comment', $this->getComment() )
639 + ActorMigration::newMigration()->getInsertValues( $dbw, 'log_user', $user );
640 $dbw->insert( 'logging', $data, __METHOD__ );
641
642 return true;
643 }
644
645 /**
646 * @since 1.12.2
647 * @deprecated in 1.31. Use UploadImporter::import
648 * @return bool
649 */
650 public function importUpload() {
651 $importer = MediaWikiServices::getInstance()->getWikiRevisionUploadImporter();
652 $statusValue = $importer->import( $this );
653 return $statusValue->isGood();
654 }
655
656 /**
657 * @since 1.12.2
658 * @deprecated in 1.31. Use UploadImporter::downloadSource
659 * @return bool|string
660 */
661 public function downloadSource() {
662 $importer = new ImportableUploadRevisionImporter(
663 $this->config->get( 'EnableUploads' ),
664 LoggerFactory::getInstance( 'UploadRevisionImporter' )
665 );
666 return $importer->downloadSource( $this );
667 }
668
669 }