MediaWiki  master
populateInterwiki.php
Go to the documentation of this file.
1 <?php
2 
28 
29 require_once __DIR__ . '/Maintenance.php';
30 
32 
36  private $source;
37 
38  public function __construct() {
39  parent::__construct();
40 
41  $this->addDescription( <<<TEXT
42 This script will populate the interwiki table, pulling in interwiki links that are used on Wikipedia
43 or another MediaWiki wiki.
44 
45 When the script has finished, it will make a note of this in the database, and will not run again
46 without the --force option.
47 
48 --source parameter is the url for the source wiki api, such as "https://en.wikipedia.org/w/api.php"
49 (the default) from which the script fetches the interwiki data and uses here to populate
50 the interwiki database table.
51 TEXT
52  );
53 
54  $this->addOption( 'source', 'Source wiki for interwiki table, such as '
55  . 'https://en.wikipedia.org/w/api.php (the default)', false, true );
56  $this->addOption( 'force', 'Run regardless of whether the database says it has '
57  . 'been run already.' );
58  }
59 
60  public function execute() {
61  $force = $this->hasOption( 'force' );
62  $this->source = $this->getOption( 'source', 'https://en.wikipedia.org/w/api.php' );
63 
64  $data = $this->fetchLinks();
65 
66  if ( $data === false ) {
67  $this->error( "Error during fetching data." );
68  } else {
69  $this->doPopulate( $data, $force );
70  }
71  }
72 
76  protected function fetchLinks() {
77  $url = wfArrayToCgi( [
78  'action' => 'query',
79  'meta' => 'siteinfo',
80  'siprop' => 'interwikimap',
81  'sifilteriw' => 'local',
82  'format' => 'json'
83  ] );
84 
85  if ( !empty( $this->source ) ) {
86  $url = rtrim( $this->source, '?' ) . '?' . $url;
87  }
88 
89  $json = MediaWikiServices::getInstance()->getHttpRequestFactory()->get( $url );
90  $data = json_decode( $json, true );
91 
92  if ( is_array( $data ) ) {
93  return $data['query']['interwikimap'];
94  } else {
95  return false;
96  }
97  }
98 
105  protected function doPopulate( array $data, $force ) {
106  $dbw = wfGetDB( DB_MASTER );
107 
108  if ( !$force ) {
109  $row = $dbw->selectRow(
110  'updatelog',
111  '1',
112  [ 'ul_key' => 'populate interwiki' ],
113  __METHOD__
114  );
115 
116  if ( $row ) {
117  $this->output( "Interwiki table already populated. Use php " .
118  "maintenance/populateInterwiki.php\n--force from the command line " .
119  "to override.\n" );
120  return true;
121  }
122  }
123 
124  $lookup = MediaWikiServices::getInstance()->getInterwikiLookup();
125  foreach ( $data as $d ) {
126  $prefix = $d['prefix'];
127 
128  $row = $dbw->selectRow(
129  'interwiki',
130  '1',
131  [ 'iw_prefix' => $prefix ],
132  __METHOD__
133  );
134 
135  if ( !$row ) {
136  $dbw->insert(
137  'interwiki',
138  [
139  'iw_prefix' => $prefix,
140  'iw_url' => $d['url'],
141  'iw_local' => 1
142  ],
143  __METHOD__,
144  [ 'IGNORE' ]
145  );
146  }
147 
148  $lookup->invalidateCache( $prefix );
149  }
150 
151  $this->output( "Interwiki links are populated.\n" );
152 
153  return true;
154  }
155 
156 }
157 
158 $maintClass = PopulateInterwiki::class;
159 require_once RUN_MAINTENANCE_IF_MAIN;
const RUN_MAINTENANCE_IF_MAIN
Definition: Maintenance.php:39
doPopulate(array $data, $force)
error( $err, $die=0)
Throw an error to the user.
getOption( $name, $default=null)
Get an option, or return the default.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
Definition: Maintenance.php:86
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
hasOption( $name)
Checks to see if a particular option exists.
A helper class for throttling authentication attempts.
const DB_MASTER
Definition: defines.php:26
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e.g.
addDescription( $text)
Set the description text.
output( $out, $channel=null)
Throw some output to the user.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.