Merge "Selenium: replace UserLoginPage with BlankPage where possible"
[lhc/web/wiklou.git] / includes / import / ImportableOldRevisionImporter.php
1 <?php
2
3 use Psr\Log\LoggerInterface;
4 use Wikimedia\Rdbms\ILoadBalancer;
5
6 /**
7 * @since 1.31
8 */
9 class ImportableOldRevisionImporter implements OldRevisionImporter {
10
11 /**
12 * @var LoggerInterface
13 */
14 private $logger;
15
16 /**
17 * @var bool
18 */
19 private $doUpdates;
20
21 /**
22 * @var ILoadBalancer
23 */
24 private $loadBalancer;
25
26 /**
27 * @param bool $doUpdates
28 * @param LoggerInterface $logger
29 * @param ILoadBalancer $loadBalancer
30 */
31 public function __construct(
32 $doUpdates,
33 LoggerInterface $logger,
34 ILoadBalancer $loadBalancer
35 ) {
36 $this->doUpdates = $doUpdates;
37 $this->logger = $logger;
38 $this->loadBalancer = $loadBalancer;
39 }
40
41 public function import( ImportableOldRevision $importableRevision, $doUpdates = true ) {
42 $dbw = $this->loadBalancer->getConnectionRef( DB_MASTER );
43
44 # Sneak a single revision into place
45 $user = $importableRevision->getUserObj() ?: User::newFromName( $importableRevision->getUser() );
46 if ( $user ) {
47 $userId = intval( $user->getId() );
48 $userText = $user->getName();
49 } else {
50 $userId = 0;
51 $userText = $importableRevision->getUser();
52 $user = new User;
53 }
54
55 // avoid memory leak...?
56 Title::clearCaches();
57
58 $page = WikiPage::factory( $importableRevision->getTitle() );
59 $page->loadPageData( 'fromdbmaster' );
60 if ( !$page->exists() ) {
61 // must create the page...
62 $pageId = $page->insertOn( $dbw );
63 $created = true;
64 $oldcountable = null;
65 } else {
66 $pageId = $page->getId();
67 $created = false;
68
69 // Note: sha1 has been in XML dumps since 2012. If you have an
70 // older dump, the duplicate detection here won't work.
71 if ( $importableRevision->getSha1Base36() !== false ) {
72 $prior = $dbw->selectField( 'revision', '1',
73 [ 'rev_page' => $pageId,
74 'rev_timestamp' => $dbw->timestamp( $importableRevision->getTimestamp() ),
75 'rev_sha1' => $importableRevision->getSha1Base36() ],
76 __METHOD__
77 );
78 if ( $prior ) {
79 // @todo FIXME: This could fail slightly for multiple matches :P
80 $this->logger->debug( __METHOD__ . ": skipping existing revision for [[" .
81 $importableRevision->getTitle()->getPrefixedText() . "]], timestamp " .
82 $importableRevision->getTimestamp() . "\n" );
83 return false;
84 }
85 }
86 }
87
88 if ( !$pageId ) {
89 // This seems to happen if two clients simultaneously try to import the
90 // same page
91 $this->logger->debug( __METHOD__ . ': got invalid $pageId when importing revision of [[' .
92 $importableRevision->getTitle()->getPrefixedText() . ']], timestamp ' .
93 $importableRevision->getTimestamp() . "\n" );
94 return false;
95 }
96
97 // Select previous version to make size diffs correct
98 // @todo This assumes that multiple revisions of the same page are imported
99 // in order from oldest to newest.
100 $prevId = $dbw->selectField( 'revision', 'rev_id',
101 [
102 'rev_page' => $pageId,
103 'rev_timestamp <= ' . $dbw->addQuotes( $dbw->timestamp( $importableRevision->getTimestamp() ) ),
104 ],
105 __METHOD__,
106 [ 'ORDER BY' => [
107 'rev_timestamp DESC',
108 'rev_id DESC', // timestamp is not unique per page
109 ]
110 ]
111 );
112
113 # @todo FIXME: Use original rev_id optionally (better for backups)
114 # Insert the row
115 $revision = new Revision( [
116 'title' => $importableRevision->getTitle(),
117 'page' => $pageId,
118 'content_model' => $importableRevision->getModel(),
119 'content_format' => $importableRevision->getFormat(),
120 // XXX: just set 'content' => $wikiRevision->getContent()?
121 'text' => $importableRevision->getContent()->serialize( $importableRevision->getFormat() ),
122 'comment' => $importableRevision->getComment(),
123 'user' => $userId,
124 'user_text' => $userText,
125 'timestamp' => $importableRevision->getTimestamp(),
126 'minor_edit' => $importableRevision->getMinor(),
127 'parent_id' => $prevId,
128 ] );
129 $revision->insertOn( $dbw );
130 $changed = $page->updateIfNewerOn( $dbw, $revision );
131
132 if ( $changed !== false && $this->doUpdates ) {
133 $this->logger->debug( __METHOD__ . ": running updates\n" );
134 // countable/oldcountable stuff is handled in WikiImporter::finishImportPage
135 $page->doEditUpdates(
136 $revision,
137 $user,
138 [ 'created' => $created, 'oldcountable' => 'no-change' ]
139 );
140 }
141
142 return true;
143 }
144
145 }