TitleValue.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <?php
  2. /**
  3. * Representation of a page title within MediaWiki.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. * http://www.gnu.org/copyleft/gpl.html
  19. *
  20. * @file
  21. * @author Daniel Kinzler
  22. */
  23. use MediaWiki\Linker\LinkTarget;
  24. use Wikimedia\Assert\Assert;
  25. use Wikimedia\Assert\ParameterTypeException;
  26. /**
  27. * Represents a page (or page fragment) title within MediaWiki.
  28. *
  29. * @note In contrast to Title, this is designed to be a plain value object. That is,
  30. * it is immutable, does not use global state, and causes no side effects.
  31. *
  32. * @see https://www.mediawiki.org/wiki/Requests_for_comment/TitleValue
  33. * @since 1.23
  34. */
  35. class TitleValue implements LinkTarget {
  36. /**
  37. * @deprecated in 1.31. This class is immutable. Use the getter for access.
  38. * @var int
  39. */
  40. protected $namespace;
  41. /**
  42. * @deprecated in 1.31. This class is immutable. Use the getter for access.
  43. * @var string
  44. */
  45. protected $dbkey;
  46. /**
  47. * @deprecated in 1.31. This class is immutable. Use the getter for access.
  48. * @var string
  49. */
  50. protected $fragment;
  51. /**
  52. * @deprecated in 1.31. This class is immutable. Use the getter for access.
  53. * @var string
  54. */
  55. protected $interwiki;
  56. /**
  57. * Text form including namespace/interwiki, initialised on demand
  58. *
  59. * Only public to share cache with TitleFormatter
  60. *
  61. * @private
  62. * @var string
  63. */
  64. public $prefixedText = null;
  65. /**
  66. * Constructs a TitleValue.
  67. *
  68. * @note TitleValue expects a valid namespace and name; typically, a TitleValue is constructed
  69. * either from a database entry, or by a TitleParser. For constructing a TitleValue from user
  70. * input or external sources, use a TitleParser.
  71. *
  72. * @param int $namespace The namespace ID. This is not validated.
  73. * @param string $title The page title in either DBkey or text form. No normalization is applied
  74. * beyond underscore/space conversion.
  75. * @param string $fragment The fragment title. Use '' to represent the whole page.
  76. * No validation or normalization is applied.
  77. * @param string $interwiki The interwiki component
  78. *
  79. * @throws InvalidArgumentException
  80. */
  81. public function __construct( $namespace, $title, $fragment = '', $interwiki = '' ) {
  82. if ( !is_int( $namespace ) ) {
  83. throw new ParameterTypeException( '$namespace', 'int' );
  84. }
  85. if ( !is_string( $title ) ) {
  86. throw new ParameterTypeException( '$title', 'string' );
  87. }
  88. if ( !is_string( $fragment ) ) {
  89. throw new ParameterTypeException( '$fragment', 'string' );
  90. }
  91. if ( !is_string( $interwiki ) ) {
  92. throw new ParameterTypeException( '$interwiki', 'string' );
  93. }
  94. // Sanity check, no full validation or normalization applied here!
  95. Assert::parameter( !preg_match( '/^[_ ]|[\r\n\t]|[_ ]$/', $title ), '$title',
  96. "invalid name '$title'" );
  97. Assert::parameter(
  98. $title !== '' ||
  99. ( $namespace === NS_MAIN && ( $fragment !== '' || $interwiki !== '' ) ),
  100. '$title',
  101. 'should not be empty unless namespace is main and fragment or interwiki is non-empty'
  102. );
  103. $this->namespace = $namespace;
  104. $this->dbkey = strtr( $title, ' ', '_' );
  105. $this->fragment = $fragment;
  106. $this->interwiki = $interwiki;
  107. }
  108. /**
  109. * @since 1.23
  110. * @return int
  111. */
  112. public function getNamespace() {
  113. return $this->namespace;
  114. }
  115. /**
  116. * @since 1.27
  117. * @param int $ns
  118. * @return bool
  119. */
  120. public function inNamespace( $ns ) {
  121. return $this->namespace == $ns;
  122. }
  123. /**
  124. * @since 1.23
  125. * @return string
  126. */
  127. public function getFragment() {
  128. return $this->fragment;
  129. }
  130. /**
  131. * @since 1.27
  132. * @return bool
  133. */
  134. public function hasFragment() {
  135. return $this->fragment !== '';
  136. }
  137. /**
  138. * Returns the title's DB key, as supplied to the constructor,
  139. * without namespace prefix or fragment.
  140. * @since 1.23
  141. *
  142. * @return string
  143. */
  144. public function getDBkey() {
  145. return $this->dbkey;
  146. }
  147. /**
  148. * Returns the title in text form,
  149. * without namespace prefix or fragment.
  150. * @since 1.23
  151. *
  152. * This is computed from the DB key by replacing any underscores with spaces.
  153. *
  154. * @note To get a title string that includes the namespace and/or fragment,
  155. * use a TitleFormatter.
  156. *
  157. * @return string
  158. */
  159. public function getText() {
  160. return str_replace( '_', ' ', $this->dbkey );
  161. }
  162. /**
  163. * Creates a new TitleValue for a different fragment of the same page.
  164. *
  165. * @since 1.27
  166. * @param string $fragment The fragment name, or "" for the entire page.
  167. *
  168. * @return TitleValue
  169. */
  170. public function createFragmentTarget( $fragment ) {
  171. return new TitleValue(
  172. $this->namespace,
  173. $this->dbkey,
  174. $fragment,
  175. $this->interwiki
  176. );
  177. }
  178. /**
  179. * Whether it has an interwiki part
  180. *
  181. * @since 1.27
  182. * @return bool
  183. */
  184. public function isExternal() {
  185. return $this->interwiki !== '';
  186. }
  187. /**
  188. * Returns the interwiki part
  189. *
  190. * @since 1.27
  191. * @return string
  192. */
  193. public function getInterwiki() {
  194. return $this->interwiki;
  195. }
  196. /**
  197. * Returns a string representation of the title, for logging. This is purely informative
  198. * and must not be used programmatically. Use the appropriate TitleFormatter to generate
  199. * the correct string representation for a given use.
  200. * @since 1.23
  201. *
  202. * @return string
  203. */
  204. public function __toString() {
  205. $name = $this->namespace . ':' . $this->dbkey;
  206. if ( $this->fragment !== '' ) {
  207. $name .= '#' . $this->fragment;
  208. }
  209. if ( $this->interwiki !== '' ) {
  210. $name = $this->interwiki . ':' . $name;
  211. }
  212. return $name;
  213. }
  214. }