Merge "Title: Refactor JS/CSS page handling to be more sane"
[lhc/web/wiklou.git] / includes / import / ImportableOldRevisionImporter.php
1 <?php
2
3 use Psr\Log\LoggerInterface;
4 use Wikimedia\Rdbms\LoadBalancer;
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 LoadBalancer
23 */
24 private $loadBalancer;
25
26 /**
27 * @param bool $doUpdates
28 * @param LoggerInterface $logger
29 * @param LoadBalancer $loadBalancer
30 */
31 public function __construct(
32 $doUpdates,
33 LoggerInterface $logger,
34 LoadBalancer $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 $prior = $dbw->selectField( 'revision', '1',
72 [ 'rev_page' => $pageId,
73 'rev_timestamp' => $dbw->timestamp( $importableRevision->getTimestamp() ),
74 'rev_sha1' => $importableRevision->getSha1Base36() ],
75 __METHOD__
76 );
77 if ( $prior ) {
78 // @todo FIXME: This could fail slightly for multiple matches :P
79 $this->logger->debug( __METHOD__ . ": skipping existing revision for [[" .
80 $importableRevision->getTitle()->getPrefixedText() . "]], timestamp " .
81 $importableRevision->getTimestamp() . "\n" );
82 return false;
83 }
84 }
85
86 if ( !$pageId ) {
87 // This seems to happen if two clients simultaneously try to import the
88 // same page
89 $this->logger->debug( __METHOD__ . ': got invalid $pageId when importing revision of [[' .
90 $importableRevision->getTitle()->getPrefixedText() . ']], timestamp ' .
91 $importableRevision->getTimestamp() . "\n" );
92 return false;
93 }
94
95 // Select previous version to make size diffs correct
96 // @todo This assumes that multiple revisions of the same page are imported
97 // in order from oldest to newest.
98 $prevId = $dbw->selectField( 'revision', 'rev_id',
99 [
100 'rev_page' => $pageId,
101 'rev_timestamp <= ' . $dbw->addQuotes( $dbw->timestamp( $importableRevision->getTimestamp() ) ),
102 ],
103 __METHOD__,
104 [ 'ORDER BY' => [
105 'rev_timestamp DESC',
106 'rev_id DESC', // timestamp is not unique per page
107 ]
108 ]
109 );
110
111 # @todo FIXME: Use original rev_id optionally (better for backups)
112 # Insert the row
113 $revision = new Revision( [
114 'title' => $importableRevision->getTitle(),
115 'page' => $pageId,
116 'content_model' => $importableRevision->getModel(),
117 'content_format' => $importableRevision->getFormat(),
118 // XXX: just set 'content' => $wikiRevision->getContent()?
119 'text' => $importableRevision->getContent()->serialize( $importableRevision->getFormat() ),
120 'comment' => $importableRevision->getComment(),
121 'user' => $userId,
122 'user_text' => $userText,
123 'timestamp' => $importableRevision->getTimestamp(),
124 'minor_edit' => $importableRevision->getMinor(),
125 'parent_id' => $prevId,
126 ] );
127 $revision->insertOn( $dbw );
128 $changed = $page->updateIfNewerOn( $dbw, $revision );
129
130 if ( $changed !== false && $this->doUpdates ) {
131 $this->logger->debug( __METHOD__ . ": running updates\n" );
132 // countable/oldcountable stuff is handled in WikiImporter::finishImportPage
133 $page->doEditUpdates(
134 $revision,
135 $user,
136 [ 'created' => $created, 'oldcountable' => 'no-change' ]
137 );
138 }
139
140 return true;
141 }
142
143 }