wiki.techinc.nl/includes/title/NamespaceAwareForeignTitleFactory.php
Timo Tijhof 1f34ac4526 title: Remove dated comment about inNamespace(), overall doc cleanup
* The Title::inNamespace() method discouraged use of getNamespace()
  for comparison.

  This was added 10 years ago in r103893 (commit 3414e91bae),
  however no such "change" has been made, and the new LinkTarget
  stable interface and TitleValue class contains the same getNamespace()
  method, and no warning against its use.

  My main reason for removing this comment is so that avoid fear
  against using `in_array()` with TitleValue->getNamespace() which
  this comment seems to discourage. While Title has plural
  inNamespaces(), TitleValue does not. This seems fine, as one can
  simply use in_array for more complex use cases where a range or
  list is compared against.

* Fix Doxygen warnings about invalid or unsupported XML tags
  such as `<a>`, `<siteinfo>` etc. Rephase or use backtics,.

* Fix useless IDE tooltips and Doxygen output by removing empty stubs
  from method overrides that add no new information, yet obscured
  the otherwise inherited parent destination which does have useful
  information.

* Clarify that `renderForComment` must not be mixed with other ones.
  This seems to be how it is intended. Upon realizing that, I think
  this is unreasonable and should perhaps be removed. For now, I've
  documented the hack that it seems to exist for.

* Consistently use imperative mood when phrasing method docs, and
  consistently use a brief first line description, and
  consistently separate it from other paragraphs and annotations
  with one line break.

Change-Id: I7e1819a5d7124c635de84bc64d2371a122195928
2022-01-18 22:25:09 +00:00

143 lines
4.7 KiB
PHP

<?php
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
/**
* A parser that translates page titles on a foreign wiki into ForeignTitle
* objects, using information about the namespace setup on the foreign site.
*/
class NamespaceAwareForeignTitleFactory implements ForeignTitleFactory {
/**
* @var array
*/
protected $foreignNamespaces;
/**
* @var array
*/
private $foreignNamespacesFlipped;
/**
* Normalizes an array name for $foreignNamespacesFlipped.
* @param string $name
* @return string
*/
private function normalizeNamespaceName( $name ) {
return strtolower( str_replace( ' ', '_', $name ) );
}
/**
* @param array|null $foreignNamespaces An array 'id' => 'name' which contains
* the complete namespace setup of the foreign wiki. Such data could be
* obtained from siteinfo/namespaces in an XML dump file, or by an action API
* query such as api.php?action=query&meta=siteinfo&siprop=namespaces. If
* this data is unavailable, use NaiveForeignTitleFactory instead.
*/
public function __construct( $foreignNamespaces ) {
$this->foreignNamespaces = $foreignNamespaces;
if ( $foreignNamespaces !== null ) {
$this->foreignNamespacesFlipped = [];
foreach ( $foreignNamespaces as $id => $name ) {
$newKey = self::normalizeNamespaceName( $name );
$this->foreignNamespacesFlipped[$newKey] = $id;
}
}
}
/**
* Create a ForeignTitle object.
*
* Based on the page title and optionally the namespace ID, of a page on a foreign wiki.
* These values could be, for example, the `<title>` and `<ns>` attributes found in an
* XML dump.
*
* @param string $title The page title
* @param int|null $ns The namespace ID, or null if this data is not available
* @return ForeignTitle
*/
public function createForeignTitle( $title, $ns = null ) {
// Export schema version 0.5 and earlier (MW 1.18 and earlier) does not
// contain a <ns> tag, so we need to be able to handle that case.
if ( $ns === null ) {
return self::parseTitleNoNs( $title );
} else {
return self::parseTitleWithNs( $title, $ns );
}
}
/**
* Helper function to parse the title when the namespace ID is not specified.
*
* @param string $title
* @return ForeignTitle
*/
protected function parseTitleNoNs( $title ) {
$pieces = explode( ':', $title, 2 );
$key = self::normalizeNamespaceName( $pieces[0] );
// Does the part before the colon match a known namespace? Check the
// foreign namespaces
$isNamespacePartValid = isset( $this->foreignNamespacesFlipped[$key] );
if ( count( $pieces ) === 2 && $isNamespacePartValid ) {
list( $namespaceName, $pageName ) = $pieces;
$ns = $this->foreignNamespacesFlipped[$key];
} else {
$namespaceName = '';
$pageName = $title;
$ns = 0;
}
return new ForeignTitle( $ns, $namespaceName, $pageName );
}
/**
* Helper function to parse the title when the namespace value is known.
*
* @param string $title
* @param int $ns
* @return ForeignTitle
*/
protected function parseTitleWithNs( $title, $ns ) {
$pieces = explode( ':', $title, 2 );
// Is $title of the form Namespace:Title (true), or just Title (false)?
$titleIncludesNamespace = ( $ns != '0' && count( $pieces ) === 2 );
if ( isset( $this->foreignNamespaces[$ns] ) ) {
$namespaceName = $this->foreignNamespaces[$ns];
} else {
// If the foreign wiki is misconfigured, XML dumps can contain a page with
// a non-zero namespace ID, but whose title doesn't contain a colon
// (T114115). In those cases, output a made-up namespace name to avoid
// collisions. The ImportTitleFactory might replace this with something
// more appropriate.
$namespaceName = $titleIncludesNamespace ? $pieces[0] : "Ns$ns";
}
// We assume that the portion of the page title before the colon is the
// namespace name, except in the case of namespace 0.
if ( $titleIncludesNamespace ) {
$pageName = $pieces[1];
} else {
$pageName = $title;
}
return new ForeignTitle( $ns, $namespaceName, $pageName );
}
}