MediaWiki  master
SiteImporter.php
Go to the documentation of this file.
1 <?php
2 
30 class SiteImporter {
31 
35  private $store;
36 
41 
45  public function __construct( SiteStore $store ) {
46  $this->store = $store;
47  }
48 
52  public function getExceptionCallback() {
54  }
55 
60  $this->exceptionCallback = $exceptionCallback;
61  }
62 
66  public function importFromFile( $file ) {
67  $xml = file_get_contents( $file );
68 
69  if ( $xml === false ) {
70  throw new RuntimeException( 'Failed to read ' . $file . '!' );
71  }
72 
73  $this->importFromXML( $xml );
74  }
75 
81  public function importFromXML( $xml ) {
82  $document = new DOMDocument();
83 
84  $oldLibXmlErrors = libxml_use_internal_errors( true );
85  $oldDisable = libxml_disable_entity_loader( true );
86  $ok = $document->loadXML( $xml, LIBXML_NONET );
87 
88  if ( !$ok ) {
89  $errors = libxml_get_errors();
90  libxml_use_internal_errors( $oldLibXmlErrors );
91  libxml_disable_entity_loader( $oldDisable );
92 
93  foreach ( $errors as $error ) {
95  throw new InvalidArgumentException(
96  'Malformed XML: ' . $error->message . ' in line ' . $error->line
97  );
98  }
99 
100  throw new InvalidArgumentException( 'Malformed XML!' );
101  }
102 
103  libxml_use_internal_errors( $oldLibXmlErrors );
104  libxml_disable_entity_loader( $oldDisable );
105  $this->importFromDOM( $document->documentElement );
106  }
107 
111  private function importFromDOM( DOMElement $root ) {
112  $sites = $this->makeSiteList( $root );
113  $this->store->saveSites( $sites );
114  }
115 
121  private function makeSiteList( DOMElement $root ) {
122  $sites = [];
123 
124  // Old sites, to get the row IDs that correspond to the global site IDs.
125  // TODO: Get rid of internal row IDs, they just get in the way. Get rid of ORMRow, too.
126  $oldSites = $this->store->getSites();
127 
128  $current = $root->firstChild;
129  while ( $current ) {
130  if ( $current instanceof DOMElement && $current->tagName === 'site' ) {
131  try {
132  $site = $this->makeSite( $current );
133  $key = $site->getGlobalId();
134 
135  if ( $oldSites->hasSite( $key ) ) {
136  $oldSite = $oldSites->getSite( $key );
137  $site->setInternalId( $oldSite->getInternalId() );
138  }
139 
140  $sites[$key] = $site;
141  } catch ( Exception $ex ) {
142  $this->handleException( $ex );
143  }
144  }
145 
146  $current = $current->nextSibling;
147  }
148 
149  return $sites;
150  }
151 
158  public function makeSite( DOMElement $siteElement ) {
159  if ( $siteElement->tagName !== 'site' ) {
160  throw new InvalidArgumentException( 'Expected <site> tag, found ' . $siteElement->tagName );
161  }
162 
163  $type = $this->getAttributeValue( $siteElement, 'type', Site::TYPE_UNKNOWN );
164  $site = Site::newForType( $type );
165 
166  $site->setForward( $this->hasChild( $siteElement, 'forward' ) );
167  $site->setGlobalId( $this->getChildText( $siteElement, 'globalid' ) );
168  $site->setGroup( $this->getChildText( $siteElement, 'group', Site::GROUP_NONE ) );
169  $site->setSource( $this->getChildText( $siteElement, 'source', Site::SOURCE_LOCAL ) );
170 
171  $pathTags = $siteElement->getElementsByTagName( 'path' );
172  for ( $i = 0; $i < $pathTags->length; $i++ ) {
173  $pathElement = $pathTags->item( $i );
174  '@phan-var DOMElement $pathElement';
175  $pathType = $this->getAttributeValue( $pathElement, 'type' );
176  $path = $pathElement->textContent;
177 
178  $site->setPath( $pathType, $path );
179  }
180 
181  $idTags = $siteElement->getElementsByTagName( 'localid' );
182  for ( $i = 0; $i < $idTags->length; $i++ ) {
183  $idElement = $idTags->item( $i );
184  '@phan-var DOMElement $idElement';
185  $idType = $this->getAttributeValue( $idElement, 'type' );
186  $id = $idElement->textContent;
187 
188  $site->addLocalId( $idType, $id );
189  }
190 
191  // @todo: import <data>
192  // @todo: import <config>
193 
194  return $site;
195  }
196 
205  private function getAttributeValue( DOMElement $element, $name, $default = false ) {
206  $node = $element->getAttributeNode( $name );
207 
208  if ( !$node ) {
209  if ( $default !== false ) {
210  return $default;
211  } else {
212  throw new MWException(
213  'Required ' . $name . ' attribute not found in <' . $element->tagName . '> tag'
214  );
215  }
216  }
217 
218  return $node->textContent;
219  }
220 
229  private function getChildText( DOMElement $element, $name, $default = false ) {
230  $elements = $element->getElementsByTagName( $name );
231 
232  if ( $elements->length < 1 ) {
233  if ( $default !== false ) {
234  return $default;
235  } else {
236  throw new MWException(
237  'Required <' . $name . '> tag not found inside <' . $element->tagName . '> tag'
238  );
239  }
240  }
241 
242  $node = $elements->item( 0 );
243  return $node->textContent;
244  }
245 
253  private function hasChild( DOMElement $element, $name ) {
254  return $this->getChildText( $element, $name, null ) !== null;
255  }
256 
260  private function handleException( Exception $ex ) {
261  if ( $this->exceptionCallback ) {
262  call_user_func( $this->exceptionCallback, $ex );
263  } else {
264  wfLogWarning( $ex->getMessage() );
265  }
266  }
267 
268 }
SiteImporter\getExceptionCallback
getExceptionCallback()
Definition: SiteImporter.php:52
SiteImporter\$exceptionCallback
callable null $exceptionCallback
Definition: SiteImporter.php:40
SiteImporter\getAttributeValue
getAttributeValue(DOMElement $element, $name, $default=false)
Definition: SiteImporter.php:205
SiteImporter\hasChild
hasChild(DOMElement $element, $name)
Definition: SiteImporter.php:253
SiteImporter\importFromXML
importFromXML( $xml)
Definition: SiteImporter.php:81
SiteImporter\makeSiteList
makeSiteList(DOMElement $root)
Definition: SiteImporter.php:121
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
SiteImporter
Definition: SiteImporter.php:30
wfLogWarning
wfLogWarning( $msg, $callerOffset=1, $level=E_USER_WARNING)
Send a warning as a PHP error and the debug log.
Definition: GlobalFunctions.php:1056
SiteImporter\__construct
__construct(SiteStore $store)
Definition: SiteImporter.php:45
SiteImporter\$store
SiteStore $store
Definition: SiteImporter.php:35
Site\newForType
static newForType( $siteType)
Definition: Site.php:656
SiteStore
Definition: SiteStore.php:29
MWException
MediaWiki exception.
Definition: MWException.php:29
Site\TYPE_UNKNOWN
const TYPE_UNKNOWN
Definition: Site.php:33
SiteImporter\getChildText
getChildText(DOMElement $element, $name, $default=false)
Definition: SiteImporter.php:229
SiteImporter\setExceptionCallback
setExceptionCallback( $exceptionCallback)
Definition: SiteImporter.php:59
SiteImporter\handleException
handleException(Exception $ex)
Definition: SiteImporter.php:260
$path
$path
Definition: NoLocalSettings.php:25
Site\GROUP_NONE
const GROUP_NONE
Definition: Site.php:36
Site\SOURCE_LOCAL
const SOURCE_LOCAL
Definition: Site.php:41
SiteImporter\importFromDOM
importFromDOM(DOMElement $root)
Definition: SiteImporter.php:111
SiteImporter\importFromFile
importFromFile( $file)
Definition: SiteImporter.php:66
SiteImporter\makeSite
makeSite(DOMElement $siteElement)
Definition: SiteImporter.php:158
$type
$type
Definition: testCompression.php:52