MediaWiki  master
ImportableOldRevisionImporter.php
Go to the documentation of this file.
1 <?php
2 
5 
10 
14  private $logger;
15 
19  private $doUpdates;
20 
24  private $loadBalancer;
25 
31  public function __construct(
32  $doUpdates,
33  LoggerInterface $logger,
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...?
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  $tags = $importableRevision->getTags();
133  if ( $tags !== [] ) {
134  ChangeTags::addTags( $tags, null, $revision->getId() );
135  }
136 
137  if ( $changed !== false && $this->doUpdates ) {
138  $this->logger->debug( __METHOD__ . ": running updates\n" );
139  // countable/oldcountable stuff is handled in WikiImporter::finishImportPage
140  $page->doEditUpdates(
141  $revision,
142  $user,
143  [ 'created' => $created, 'oldcountable' => 'no-change' ]
144  );
145  }
146 
147  return true;
148  }
149 
150 }
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:142
__construct( $doUpdates, LoggerInterface $logger, ILoadBalancer $loadBalancer)
static clearCaches()
Definition: Title.php:3301
const DB_MASTER
Definition: defines.php:26
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
Definition: User.php:51
insertOn( $dbw)
Insert a new revision into the database, returning the new revision ID number on success and dies hor...
Definition: Revision.php:948
getConnectionRef( $i, $groups=[], $domain=false, $flags=0)
Get a live database handle reference for a real or virtual (DB_MASTER/DB_REPLICA) server index...
Database cluster connection, tracking, load balancing, and transaction manager interface.
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:515
static addTags( $tags, $rc_id=null, $rev_id=null, $log_id=null, $params=null, RecentChange $rc=null)
Add tags to a change given its rc_id, rev_id and/or log_id.
Definition: ChangeTags.php:251
return true
Definition: router.php:92