Localisation updates from https://translatewiki.net.
[mediawiki.git] / includes / site / Site.php
blobbf6925c4563aa0ec2913ca01c37b15f2365443f8
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
18 * @file
21 namespace MediaWiki\Site;
23 use InvalidArgumentException;
24 use MediaWiki\MainConfigNames;
25 use MediaWiki\MediaWikiServices;
26 use RuntimeException;
27 use UnexpectedValueException;
29 /**
30 * Represents a single site.
32 * @since 1.21
33 * @ingroup Site
34 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
36 class Site {
37 public const TYPE_UNKNOWN = 'unknown';
38 public const TYPE_MEDIAWIKI = 'mediawiki';
40 public const GROUP_NONE = 'none';
42 public const ID_INTERWIKI = 'interwiki';
43 public const ID_EQUIVALENT = 'equivalent';
45 public const SOURCE_LOCAL = 'local';
47 public const PATH_LINK = 'link';
49 /**
50 * A version ID that identifies the serialization structure used by getSerializationData()
51 * and unserialize(). This is useful for constructing cache keys in cases where the cache relies
52 * on serialization for storing the SiteList.
54 * @var string A string uniquely identifying the version of the serialization structure.
56 public const SERIAL_VERSION_ID = '2013-01-23';
58 /**
59 * @since 1.21
61 * @var string|null
63 protected $globalId = null;
65 /**
66 * @since 1.21
68 * @var string
70 protected $type = self::TYPE_UNKNOWN;
72 /**
73 * @since 1.21
75 * @var string
77 protected $group = self::GROUP_NONE;
79 /**
80 * @since 1.21
82 * @var string
84 protected $source = self::SOURCE_LOCAL;
86 /**
87 * @since 1.21
89 * @var string|null
91 protected $languageCode = null;
93 /**
94 * Holds the local ids for this site.
95 * local id type => [ ids for this type (strings) ]
97 * @since 1.21
99 * @var string[][]|false
101 protected $localIds = [];
104 * @since 1.21
106 * @var array
108 protected $extraData = [];
111 * @since 1.21
113 * @var array
115 protected $extraConfig = [];
118 * @since 1.21
120 * @var bool
122 protected $forward = false;
125 * @since 1.21
127 * @var int|null
129 protected $internalId = null;
132 * @since 1.21
134 * @param string $type
136 public function __construct( $type = self::TYPE_UNKNOWN ) {
137 $this->type = $type;
141 * Returns the global site identifier (ie enwiktionary).
143 * @since 1.21
145 * @return string|null
147 public function getGlobalId() {
148 return $this->globalId;
152 * Sets the global site identifier (ie enwiktionary).
154 * @since 1.21
155 * @param string|null $globalId
157 public function setGlobalId( ?string $globalId ) {
158 $this->globalId = $globalId;
162 * Returns the type of the site (ie mediawiki).
164 * @since 1.21
166 * @return string
168 public function getType() {
169 return $this->type;
173 * Gets the group of the site (ie wikipedia).
175 * @since 1.21
177 * @return string
179 public function getGroup() {
180 return $this->group;
184 * Sets the group of the site (ie wikipedia).
186 * @since 1.21
187 * @param string $group
189 public function setGroup( string $group ) {
190 $this->group = $group;
194 * Returns the source of the site data (ie 'local', 'wikidata', 'my-magical-repo').
196 * @since 1.21
198 * @return string
200 public function getSource() {
201 return $this->source;
205 * Sets the source of the site data (ie 'local', 'wikidata', 'my-magical-repo').
207 * @since 1.21
208 * @param string $source
210 public function setSource( string $source ) {
211 $this->source = $source;
215 * Gets if site.tld/path/key:pageTitle should forward users to the page on
216 * the actual site, where "key" is the local identifier.
218 * @since 1.21
220 * @return bool
222 public function shouldForward() {
223 return $this->forward;
227 * Sets if site.tld/path/key:pageTitle should forward users to the page on
228 * the actual site, where "key" is the local identifier.
230 * @since 1.21
231 * @param bool $shouldForward
233 public function setForward( bool $shouldForward ) {
234 $this->forward = $shouldForward;
238 * Returns the domain of the site, ie en.wikipedia.org
239 * Or null if it's not known.
241 * @since 1.21
243 * @return string|null
245 public function getDomain(): ?string {
246 $path = $this->getLinkPath();
248 if ( $path === null ) {
249 return null;
252 $domain = parse_url( $path, PHP_URL_HOST );
254 if ( $domain === false ) {
255 $domain = null;
258 return $domain;
262 * Returns the protocol of the site.
264 * @since 1.21
265 * @return string
267 public function getProtocol() {
268 $path = $this->getLinkPath();
270 if ( $path === null ) {
271 return '';
274 $protocol = parse_url( $path, PHP_URL_SCHEME );
276 // Malformed URL
277 if ( $protocol === false ) {
278 throw new UnexpectedValueException( "failed to parse URL '$path'" );
281 // Used for protocol relative URLs
282 return $protocol ?? '';
286 * Set the path used to construct links with.
288 * Shall be equivalent to setPath( getLinkPathType(), $fullUrl ).
290 * @param string $fullUrl
291 * @since 1.21
293 public function setLinkPath( $fullUrl ) {
294 $type = $this->getLinkPathType();
296 if ( $type === null ) {
297 throw new RuntimeException( "This Site does not support link paths." );
300 $this->setPath( $type, $fullUrl );
304 * Returns the path used to construct links with or false if there is no such path.
306 * Shall be equivalent to getPath( getLinkPathType() ).
308 * @return string|null
310 public function getLinkPath() {
311 $type = $this->getLinkPathType();
312 return $type === null ? null : $this->getPath( $type );
316 * Returns the main path type, that is the type of the path that should
317 * generally be used to construct links to the target site.
319 * This default implementation returns Site::PATH_LINK as the default path
320 * type. Subclasses can override this to define a different default path
321 * type, or return false to disable site links.
323 * @since 1.21
325 * @return string|null
327 public function getLinkPathType() {
328 return self::PATH_LINK;
332 * Get the full URL for the given page on the site.
334 * Returns null if the needed information is not known.
336 * This generated URL is usually based upon the path returned by getLinkPath(),
337 * but this is not a requirement.
339 * This implementation returns a URL constructed using the path returned by getLinkPath().
341 * @since 1.21
342 * @param string|false $pageName
343 * @return string|null
345 public function getPageUrl( $pageName = false ) {
346 $url = $this->getLinkPath();
348 if ( $url === null ) {
349 return null;
352 if ( $pageName !== false ) {
353 $url = str_replace( '$1', rawurlencode( $pageName ), $url );
356 return $url;
360 * Attempt to normalize the page name in some fashion.
361 * May return false to indicate various kinds of failure.
363 * This implementation returns $pageName without changes.
365 * @see Site::normalizePageName
367 * @since 1.21
368 * @since 1.37 Added $followRedirect
370 * @param string $pageName
371 * @param int $followRedirect either MediaWikiPageNameNormalizer::FOLLOW_REDIRECT or
372 * MediaWikiPageNameNormalizer::NOFOLLOW_REDIRECT
374 * @return string|false
376 public function normalizePageName( $pageName, $followRedirect = MediaWikiPageNameNormalizer::FOLLOW_REDIRECT ) {
377 return $pageName;
381 * Returns the type specific fields.
383 * @since 1.21
385 * @return array
387 public function getExtraData() {
388 return $this->extraData;
392 * Sets the type specific fields.
394 * @since 1.21
396 * @param array $extraData
398 public function setExtraData( array $extraData ) {
399 $this->extraData = $extraData;
403 * Returns the type specific config.
405 * @since 1.21
407 * @return array
409 public function getExtraConfig() {
410 return $this->extraConfig;
414 * Sets the type specific config.
416 * @since 1.21
418 * @param array $extraConfig
420 public function setExtraConfig( array $extraConfig ) {
421 $this->extraConfig = $extraConfig;
425 * Returns language code of the sites primary language.
426 * Or null if it's not known.
428 * @since 1.21
430 * @return string|null
432 public function getLanguageCode() {
433 return $this->languageCode;
437 * Sets language code of the sites primary language.
439 * @since 1.21
441 * @param string|null $languageCode
443 public function setLanguageCode( $languageCode ) {
444 if ( $languageCode !== null &&
445 !MediaWikiServices::getInstance()->getLanguageNameUtils()->isValidCode( $languageCode ) ) {
446 throw new InvalidArgumentException( "$languageCode is not a valid language code." );
448 $this->languageCode = $languageCode;
452 * Returns the set internal identifier for the site.
454 * @since 1.21
456 * @return int|null
458 public function getInternalId() {
459 return $this->internalId;
463 * Sets the internal identifier for the site.
464 * This typically is a primary key in a db table.
466 * @since 1.21
468 * @param int|null $internalId
470 public function setInternalId( $internalId = null ) {
471 $this->internalId = $internalId;
475 * Adds a local identifier.
477 * @since 1.21
479 * @param string $type
480 * @param string $identifier
482 public function addLocalId( $type, $identifier ) {
483 if ( $this->localIds === false ) {
484 $this->localIds = [];
487 $this->localIds[$type] ??= [];
489 if ( !in_array( $identifier, $this->localIds[$type] ) ) {
490 $this->localIds[$type][] = $identifier;
495 * Adds an interwiki id to the site.
497 * @since 1.21
499 * @param string $identifier
501 public function addInterwikiId( $identifier ) {
502 $this->addLocalId( self::ID_INTERWIKI, $identifier );
506 * Adds a navigation id to the site.
508 * @since 1.21
510 * @param string $identifier
512 public function addNavigationId( $identifier ) {
513 $this->addLocalId( self::ID_EQUIVALENT, $identifier );
517 * Returns the interwiki link identifiers that can be used for this site.
519 * @since 1.21
521 * @return string[]
523 public function getInterwikiIds() {
524 return $this->localIds[self::ID_INTERWIKI] ?? [];
528 * Returns the equivalent link identifiers that can be used to make
529 * the site show up in interfaces such as the "language links" section.
531 * @since 1.21
533 * @return string[]
535 public function getNavigationIds() {
536 return $this->localIds[self::ID_EQUIVALENT] ?? [];
540 * Returns all local ids
542 * @since 1.21
544 * @return array[]
546 public function getLocalIds() {
547 return $this->localIds;
551 * Set the path used to construct links with.
553 * Shall be equivalent to setPath( getLinkPathType(), $fullUrl ).
555 * @since 1.21
556 * @param string $pathType
557 * @param string $fullUrl
559 public function setPath( $pathType, string $fullUrl ) {
560 $this->extraData['paths'][$pathType] = $fullUrl;
564 * Returns the path of the provided type or null if there is no such path.
566 * @since 1.21
568 * @param string $pathType
570 * @return string|null
572 public function getPath( $pathType ) {
573 $paths = $this->getAllPaths();
574 return $paths[$pathType] ?? null;
578 * Returns the paths as associative array.
579 * The keys are path types, the values are the path urls.
581 * @since 1.21
583 * @return string[]
585 public function getAllPaths() {
586 return $this->extraData['paths'] ?? [];
590 * Removes the path of the provided type if it's set.
592 * @since 1.21
594 * @param string $pathType
596 public function removePath( $pathType ) {
597 if ( array_key_exists( 'paths', $this->extraData ) ) {
598 unset( $this->extraData['paths'][$pathType] );
603 * @since 1.21
605 * @param string $siteType
607 * @return Site
609 public static function newForType( $siteType ) {
610 /** @var class-string<Site>[] $siteTypes */
611 $siteTypes = MediaWikiServices::getInstance()->getMainConfig()->get(
612 MainConfigNames::SiteTypes
615 if ( array_key_exists( $siteType, $siteTypes ) ) {
616 return new $siteTypes[$siteType]();
619 return new Site();
623 * @see Serializable::serialize
625 * @since 1.38
627 * @return array
629 public function __serialize() {
630 return [
631 'globalid' => $this->globalId,
632 'type' => $this->type,
633 'group' => $this->group,
634 'source' => $this->source,
635 'language' => $this->languageCode,
636 'localids' => $this->localIds,
637 'config' => $this->extraConfig,
638 'data' => $this->extraData,
639 'forward' => $this->forward,
640 'internalid' => $this->internalId,
645 * @see Serializable::unserialize
647 * @since 1.38
649 * @param array $fields
651 public function __unserialize( $fields ) {
652 $this->__construct( $fields['type'] );
654 $this->setGlobalId( $fields['globalid'] );
655 $this->setGroup( $fields['group'] );
656 $this->setSource( $fields['source'] );
657 $this->setLanguageCode( $fields['language'] );
658 $this->localIds = $fields['localids'];
659 $this->setExtraConfig( $fields['config'] );
660 $this->setExtraData( $fields['data'] );
661 $this->setForward( $fields['forward'] );
662 $this->setInternalId( $fields['internalid'] );
666 /** @deprecated class alias since 1.42 */
667 class_alias( Site::class, 'Site' );