MediaWiki  master
TitleTest.php
Go to the documentation of this file.
1 <?php
2 
6 
12  protected function setUp() {
13  parent::setUp();
14 
15  $this->setMwGlobals( [
16  'wgAllowUserJs' => false,
17  'wgDefaultLanguageVariant' => false,
18  'wgMetaNamespace' => 'Project',
19  ] );
20  $this->setUserLang( 'en' );
21  $this->setContentLang( 'en' );
22  }
23 
24  protected function tearDown() {
25  // For testNewMainPage
27  parent::tearDown();
28  }
29 
33  public function testLegalChars() {
34  $titlechars = Title::legalChars();
35 
36  foreach ( range( 1, 255 ) as $num ) {
37  $chr = chr( $num );
38  if ( strpos( "#[]{}<>|", $chr ) !== false || preg_match( "/[\\x00-\\x1f\\x7f]/", $chr ) ) {
39  $this->assertFalse(
40  (bool)preg_match( "/[$titlechars]/", $chr ),
41  "chr($num) = $chr is not a valid titlechar"
42  );
43  } else {
44  $this->assertTrue(
45  (bool)preg_match( "/[$titlechars]/", $chr ),
46  "chr($num) = $chr is a valid titlechar"
47  );
48  }
49  }
50  }
51 
52  public static function provideValidSecureAndSplit() {
53  return [
54  [ 'Sandbox' ],
55  [ 'A "B"' ],
56  [ 'A \'B\'' ],
57  [ '.com' ],
58  [ '~' ],
59  [ '#' ],
60  [ '"' ],
61  [ '\'' ],
62  [ 'Talk:Sandbox' ],
63  [ 'Talk:Foo:Sandbox' ],
64  [ 'File:Example.svg' ],
65  [ 'File_talk:Example.svg' ],
66  [ 'Foo/.../Sandbox' ],
67  [ 'Sandbox/...' ],
68  [ 'A~~' ],
69  [ ':A' ],
70  // Length is 256 total, but only title part matters
71  [ 'Category:' . str_repeat( 'x', 248 ) ],
72  [ str_repeat( 'x', 252 ) ],
73  // interwiki prefix
74  [ 'localtestiw: #anchor' ],
75  [ 'localtestiw:' ],
76  [ 'localtestiw:foo' ],
77  [ 'localtestiw: foo # anchor' ],
78  [ 'localtestiw: Talk: Sandbox # anchor' ],
79  [ 'remotetestiw:' ],
80  [ 'remotetestiw: Talk: # anchor' ],
81  [ 'remotetestiw: #bar' ],
82  [ 'remotetestiw: Talk:' ],
83  [ 'remotetestiw: Talk: Foo' ],
84  [ 'localtestiw:remotetestiw:' ],
85  [ 'localtestiw:remotetestiw:foo' ]
86  ];
87  }
88 
89  public static function provideInvalidSecureAndSplit() {
90  return [
91  [ '', 'title-invalid-empty' ],
92  [ ':', 'title-invalid-empty' ],
93  [ '__ __', 'title-invalid-empty' ],
94  [ ' __ ', 'title-invalid-empty' ],
95  // Bad characters forbidden regardless of wgLegalTitleChars
96  [ 'A [ B', 'title-invalid-characters' ],
97  [ 'A ] B', 'title-invalid-characters' ],
98  [ 'A { B', 'title-invalid-characters' ],
99  [ 'A } B', 'title-invalid-characters' ],
100  [ 'A < B', 'title-invalid-characters' ],
101  [ 'A > B', 'title-invalid-characters' ],
102  [ 'A | B', 'title-invalid-characters' ],
103  [ "A \t B", 'title-invalid-characters' ],
104  [ "A \n B", 'title-invalid-characters' ],
105  // URL encoding
106  [ 'A%20B', 'title-invalid-characters' ],
107  [ 'A%23B', 'title-invalid-characters' ],
108  [ 'A%2523B', 'title-invalid-characters' ],
109  // XML/HTML character entity references
110  // Note: Commented out because they are not marked invalid by the PHP test as
111  // Title::newFromText runs Sanitizer::decodeCharReferencesAndNormalize first.
112  // 'A &eacute; B',
113  // 'A &#233; B',
114  // 'A &#x00E9; B',
115  // Subject of NS_TALK does not roundtrip to NS_MAIN
116  [ 'Talk:File:Example.svg', 'title-invalid-talk-namespace' ],
117  // Directory navigation
118  [ '.', 'title-invalid-relative' ],
119  [ '..', 'title-invalid-relative' ],
120  [ './Sandbox', 'title-invalid-relative' ],
121  [ '../Sandbox', 'title-invalid-relative' ],
122  [ 'Foo/./Sandbox', 'title-invalid-relative' ],
123  [ 'Foo/../Sandbox', 'title-invalid-relative' ],
124  [ 'Sandbox/.', 'title-invalid-relative' ],
125  [ 'Sandbox/..', 'title-invalid-relative' ],
126  // Tilde
127  [ 'A ~~~ Name', 'title-invalid-magic-tilde' ],
128  [ 'A ~~~~ Signature', 'title-invalid-magic-tilde' ],
129  [ 'A ~~~~~ Timestamp', 'title-invalid-magic-tilde' ],
130  // Length
131  [ str_repeat( 'x', 256 ), 'title-invalid-too-long' ],
132  // Namespace prefix without actual title
133  [ 'Talk:', 'title-invalid-empty' ],
134  [ 'Talk:#', 'title-invalid-empty' ],
135  [ 'Category: ', 'title-invalid-empty' ],
136  [ 'Category: #bar', 'title-invalid-empty' ],
137  // interwiki prefix
138  [ 'localtestiw: Talk: # anchor', 'title-invalid-empty' ],
139  [ 'localtestiw: Talk:', 'title-invalid-empty' ]
140  ];
141  }
142 
143  private function secureAndSplitGlobals() {
144  $this->setMwGlobals( [
145  'wgLocalInterwikis' => [ 'localtestiw' ],
146  'wgHooks' => [
147  'InterwikiLoadPrefix' => [
148  function ( $prefix, &$data ) {
149  if ( $prefix === 'localtestiw' ) {
150  $data = [ 'iw_url' => 'localtestiw' ];
151  } elseif ( $prefix === 'remotetestiw' ) {
152  $data = [ 'iw_url' => 'remotetestiw' ];
153  }
154  return false;
155  }
156  ]
157  ]
158  ] );
159 
160  $this->overrideMwServices();
161  }
162 
169  public function testSecureAndSplitValid( $text ) {
170  $this->secureAndSplitGlobals();
171  $this->assertInstanceOf( Title::class, Title::newFromText( $text ), "Valid: $text" );
172  }
173 
180  public function testSecureAndSplitInvalid( $text, $expectedErrorMessage ) {
181  $this->secureAndSplitGlobals();
182  try {
183  Title::newFromTextThrow( $text ); // should throw
184  $this->assertTrue( false, "Invalid: $text" );
185  } catch ( MalformedTitleException $ex ) {
186  $this->assertEquals( $expectedErrorMessage, $ex->getErrorMessage(), "Invalid: $text" );
187  }
188  }
189 
190  public static function provideConvertByteClassToUnicodeClass() {
191  return [
192  [
193  ' %!"$&\'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+',
194  ' %!"$&\'()*,\\-./0-9:;=?@A-Z\\\\\\^_`a-z~+\\u0080-\\uFFFF',
195  ],
196  [
197  'QWERTYf-\\xFF+',
198  'QWERTYf-\\x7F+\\u0080-\\uFFFF',
199  ],
200  [
201  'QWERTY\\x66-\\xFD+',
202  'QWERTYf-\\x7F+\\u0080-\\uFFFF',
203  ],
204  [
205  'QWERTYf-y+',
206  'QWERTYf-y+',
207  ],
208  [
209  'QWERTYf-\\x80+',
210  'QWERTYf-\\x7F+\\u0080-\\uFFFF',
211  ],
212  [
213  'QWERTY\\x66-\\x80+\\x23',
214  'QWERTYf-\\x7F+#\\u0080-\\uFFFF',
215  ],
216  [
217  'QWERTY\\x66-\\x80+\\xD3',
218  'QWERTYf-\\x7F+\\u0080-\\uFFFF',
219  ],
220  [
221  '\\\\\\x99',
222  '\\\\\\u0080-\\uFFFF',
223  ],
224  [
225  '-\\x99',
226  '\\-\\u0080-\\uFFFF',
227  ],
228  [
229  'QWERTY\\-\\x99',
230  'QWERTY\\-\\u0080-\\uFFFF',
231  ],
232  [
233  '\\\\x99',
234  '\\\\x99',
235  ],
236  [
237  'A-\\x9F',
238  'A-\\x7F\\u0080-\\uFFFF',
239  ],
240  [
241  '\\x66-\\x77QWERTY\\x88-\\x91FXZ',
242  'f-wQWERTYFXZ\\u0080-\\uFFFF',
243  ],
244  [
245  '\\x66-\\x99QWERTY\\xAA-\\xEEFXZ',
246  'f-\\x7FQWERTYFXZ\\u0080-\\uFFFF',
247  ],
248  ];
249  }
250 
255  public function testConvertByteClassToUnicodeClass( $byteClass, $unicodeClass ) {
256  $this->assertEquals( $unicodeClass, Title::convertByteClassToUnicodeClass( $byteClass ) );
257  }
258 
263  public function testFixSpecialNameRetainsParameter( $text, $expectedParam ) {
264  $title = Title::newFromText( $text );
265  $fixed = $title->fixSpecialName();
266  $stuff = explode( '/', $fixed->getDBkey(), 2 );
267  if ( count( $stuff ) == 2 ) {
268  $par = $stuff[1];
269  } else {
270  $par = null;
271  }
272  $this->assertEquals(
273  $expectedParam,
274  $par,
275  "T33100 regression check: Title->fixSpecialName() should preserve parameter"
276  );
277  }
278 
280  return [
281  [ 'Special:Version', null ],
282  [ 'Special:Version/', '' ],
283  [ 'Special:Version/param', 'param' ],
284  ];
285  }
286 
296  public function testIsValidMoveOperation( $source, $target, $expected ) {
297  $this->setMwGlobals( 'wgContentHandlerUseDB', false );
299  $nt = Title::newFromText( $target );
300  $errors = $title->isValidMoveOperation( $nt, false );
301  if ( $expected === true ) {
302  $this->assertTrue( $errors );
303  } else {
304  $errors = $this->flattenErrorsArray( $errors );
305  foreach ( (array)$expected as $error ) {
306  $this->assertContains( $error, $errors );
307  }
308  }
309  }
310 
311  public static function provideTestIsValidMoveOperation() {
312  return [
313  // for Title::isValidMoveOperation
314  [ 'Some page', '', 'badtitletext' ],
315  [ 'Test', 'Test', 'selfmove' ],
316  [ 'Special:FooBar', 'Test', 'immobile-source-namespace' ],
317  [ 'Test', 'Special:FooBar', 'immobile-target-namespace' ],
318  [ 'MediaWiki:Common.js', 'Help:Some wikitext page', 'bad-target-model' ],
319  [ 'Page', 'File:Test.jpg', 'nonfile-cannot-move-to-file' ],
320  [ 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ],
321  ];
322  }
323 
335  public function testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected ) {
336  // $wgWhitelistReadRegexp must be an array. Since the provided test cases
337  // usually have only one regex, it is more concise to write the lonely regex
338  // as a string. Thus we cast to an array() to honor $wgWhitelistReadRegexp
339  // type requisite.
340  if ( is_string( $whitelistRegexp ) ) {
341  $whitelistRegexp = [ $whitelistRegexp ];
342  }
343 
344  $this->setMwGlobals( [
345  // So User::isEveryoneAllowed( 'read' ) === false
346  'wgGroupPermissions' => [ '*' => [ 'read' => false ] ],
347  'wgWhitelistRead' => [ 'some random non sense title' ],
348  'wgWhitelistReadRegexp' => $whitelistRegexp,
349  ] );
350 
352 
353  // New anonymous user with no rights
354  $user = new User;
355  $user->mRights = [];
356  $errors = $title->userCan( $action, $user );
357 
358  if ( is_bool( $expected ) ) {
359  # Forge the assertion message depending on the assertion expectation
360  $allowableness = $expected
361  ? " should be allowed"
362  : " should NOT be allowed";
363  $this->assertEquals(
364  $expected,
365  $errors,
366  "User action '$action' on [[$source]] $allowableness."
367  );
368  } else {
369  $errors = $this->flattenErrorsArray( $errors );
370  foreach ( (array)$expected as $error ) {
371  $this->assertContains( $error, $errors );
372  }
373  }
374  }
375 
379  public function dataWgWhitelistReadRegexp() {
380  $ALLOWED = true;
381  $DISALLOWED = false;
382 
383  return [
384  // Everything, if this doesn't work, we're really in trouble
385  [ '/.*/', 'Main_Page', 'read', $ALLOWED ],
386  [ '/.*/', 'Main_Page', 'edit', $DISALLOWED ],
387 
388  // We validate against the title name, not the db key
389  [ '/^Main_Page$/', 'Main_Page', 'read', $DISALLOWED ],
390  // Main page
391  [ '/^Main/', 'Main_Page', 'read', $ALLOWED ],
392  [ '/^Main.*/', 'Main_Page', 'read', $ALLOWED ],
393  // With spaces
394  [ '/Mic\sCheck/', 'Mic Check', 'read', $ALLOWED ],
395  // Unicode multibyte
396  // ...without unicode modifier
397  [ '/Unicode Test . Yes/', 'Unicode Test Ñ Yes', 'read', $DISALLOWED ],
398  // ...with unicode modifier
399  [ '/Unicode Test . Yes/u', 'Unicode Test Ñ Yes', 'read', $ALLOWED ],
400  // Case insensitive
401  [ '/MiC ChEcK/', 'mic check', 'read', $DISALLOWED ],
402  [ '/MiC ChEcK/i', 'mic check', 'read', $ALLOWED ],
403 
404  // From DefaultSettings.php:
405  [ "@^UsEr.*@i", 'User is banned', 'read', $ALLOWED ],
406  [ "@^UsEr.*@i", 'User:John Doe', 'read', $ALLOWED ],
407 
408  // With namespaces:
409  [ '/^Special:NewPages$/', 'Special:NewPages', 'read', $ALLOWED ],
410  [ null, 'Special:Newpages', 'read', $DISALLOWED ],
411 
412  ];
413  }
414 
415  public function flattenErrorsArray( $errors ) {
416  $result = [];
417  foreach ( $errors as $error ) {
418  $result[] = $error[0];
419  }
420 
421  return $result;
422  }
423 
428  public function testGetPageViewLanguage( $expected, $titleText, $contLang,
429  $lang, $variant, $msg = ''
430  ) {
431  // Setup environnement for this test
432  $this->setMwGlobals( [
433  'wgDefaultLanguageVariant' => $variant,
434  'wgAllowUserJs' => true,
435  ] );
436  $this->setUserLang( $lang );
437  $this->setContentLang( $contLang );
438 
439  $title = Title::newFromText( $titleText );
440  $this->assertInstanceOf( Title::class, $title,
441  "Test must be passed a valid title text, you gave '$titleText'"
442  );
443  $this->assertEquals( $expected,
444  $title->getPageViewLanguage()->getCode(),
445  $msg
446  );
447  }
448 
449  public static function provideGetPageViewLanguage() {
450  # Format:
451  # - expected
452  # - Title name
453  # - content language (expected in most cases)
454  # - wgLang (on some specific pages)
455  # - wgDefaultLanguageVariant
456  # - Optional message
457  return [
458  [ 'fr', 'Help:I_need_somebody', 'fr', 'fr', false ],
459  [ 'es', 'Help:I_need_somebody', 'es', 'zh-tw', false ],
460  [ 'zh', 'Help:I_need_somebody', 'zh', 'zh-tw', false ],
461 
462  [ 'es', 'Help:I_need_somebody', 'es', 'zh-tw', 'zh-cn' ],
463  [ 'es', 'MediaWiki:About', 'es', 'zh-tw', 'zh-cn' ],
464  [ 'es', 'MediaWiki:About/', 'es', 'zh-tw', 'zh-cn' ],
465  [ 'de', 'MediaWiki:About/de', 'es', 'zh-tw', 'zh-cn' ],
466  [ 'en', 'MediaWiki:Common.js', 'es', 'zh-tw', 'zh-cn' ],
467  [ 'en', 'MediaWiki:Common.css', 'es', 'zh-tw', 'zh-cn' ],
468  [ 'en', 'User:JohnDoe/Common.js', 'es', 'zh-tw', 'zh-cn' ],
469  [ 'en', 'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ],
470 
471  [ 'zh-cn', 'Help:I_need_somebody', 'zh', 'zh-tw', 'zh-cn' ],
472  [ 'zh', 'MediaWiki:About', 'zh', 'zh-tw', 'zh-cn' ],
473  [ 'zh', 'MediaWiki:About/', 'zh', 'zh-tw', 'zh-cn' ],
474  [ 'de', 'MediaWiki:About/de', 'zh', 'zh-tw', 'zh-cn' ],
475  [ 'zh-cn', 'MediaWiki:About/zh-cn', 'zh', 'zh-tw', 'zh-cn' ],
476  [ 'zh-tw', 'MediaWiki:About/zh-tw', 'zh', 'zh-tw', 'zh-cn' ],
477  [ 'en', 'MediaWiki:Common.js', 'zh', 'zh-tw', 'zh-cn' ],
478  [ 'en', 'MediaWiki:Common.css', 'zh', 'zh-tw', 'zh-cn' ],
479  [ 'en', 'User:JohnDoe/Common.js', 'zh', 'zh-tw', 'zh-cn' ],
480  [ 'en', 'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ],
481 
482  [ 'zh-tw', 'Special:NewPages', 'es', 'zh-tw', 'zh-cn' ],
483  [ 'zh-tw', 'Special:NewPages', 'zh', 'zh-tw', 'zh-cn' ],
484 
485  ];
486  }
487 
492  public function testGetBaseText( $title, $expected, $msg = '' ) {
494  $this->assertEquals( $expected,
495  $title->getBaseText(),
496  $msg
497  );
498  }
499 
500  public static function provideBaseTitleCases() {
501  return [
502  # Title, expected base, optional message
503  [ 'User:John_Doe/subOne/subTwo', 'John Doe/subOne' ],
504  [ 'User:Foo/Bar/Baz', 'Foo/Bar' ],
505  ];
506  }
507 
512  public function testGetRootText( $title, $expected, $msg = '' ) {
514  $this->assertEquals( $expected,
515  $title->getRootText(),
516  $msg
517  );
518  }
519 
520  public static function provideRootTitleCases() {
521  return [
522  # Title, expected base, optional message
523  [ 'User:John_Doe/subOne/subTwo', 'John Doe' ],
524  [ 'User:Foo/Bar/Baz', 'Foo' ],
525  ];
526  }
527 
533  public function testGetSubpageText( $title, $expected, $msg = '' ) {
535  $this->assertEquals( $expected,
536  $title->getSubpageText(),
537  $msg
538  );
539  }
540 
541  public static function provideSubpageTitleCases() {
542  return [
543  # Title, expected base, optional message
544  [ 'User:John_Doe/subOne/subTwo', 'subTwo' ],
545  [ 'User:John_Doe/subOne', 'subOne' ],
546  ];
547  }
548 
549  public static function provideNewFromTitleValue() {
550  return [
551  [ new TitleValue( NS_MAIN, 'Foo' ) ],
552  [ new TitleValue( NS_MAIN, 'Foo', 'bar' ) ],
553  [ new TitleValue( NS_USER, 'Hansi_Maier' ) ],
554  ];
555  }
556 
562  $title = Title::newFromTitleValue( $value );
563 
564  $dbkey = str_replace( ' ', '_', $value->getText() );
565  $this->assertEquals( $dbkey, $title->getDBkey() );
566  $this->assertEquals( $value->getNamespace(), $title->getNamespace() );
567  $this->assertEquals( $value->getFragment(), $title->getFragment() );
568  }
569 
575  $title = Title::newFromLinkTarget( $value );
576 
577  $dbkey = str_replace( ' ', '_', $value->getText() );
578  $this->assertEquals( $dbkey, $title->getDBkey() );
579  $this->assertEquals( $value->getNamespace(), $title->getNamespace() );
580  $this->assertEquals( $value->getFragment(), $title->getFragment() );
581  }
582 
586  public function testNewFromLinkTarget_clone() {
587  $title = Title::newFromText( __METHOD__ );
588  $this->assertSame( $title, Title::newFromLinkTarget( $title ) );
589 
590  // The Title::NEW_CLONE flag should ensure that a fresh instance is returned.
592  $this->assertNotSame( $title, $clone );
593  $this->assertTrue( $clone->equals( $title ) );
594  }
595 
596  public function provideCastFromLinkTarget() {
597  return array_merge( [ [ null ] ], self::provideNewFromTitleValue() );
598  }
599 
604  public function testCastFromLinkTarget( $value ) {
606 
607  if ( $value === null ) {
608  $this->assertNull( $title );
609  } else {
610  $dbkey = str_replace( ' ', '_', $value->getText() );
611  $this->assertSame( $dbkey, $title->getDBkey() );
612  $this->assertSame( $value->getNamespace(), $title->getNamespace() );
613  $this->assertSame( $value->getFragment(), $title->getFragment() );
614  }
615  }
616 
617  public static function provideGetTitleValue() {
618  return [
619  [ 'Foo' ],
620  [ 'Foo#bar' ],
621  [ 'User:Hansi_Maier' ],
622  ];
623  }
624 
629  public function testGetTitleValue( $text ) {
630  $title = Title::newFromText( $text );
631  $value = $title->getTitleValue();
632 
633  $dbkey = str_replace( ' ', '_', $value->getText() );
634  $this->assertEquals( $title->getDBkey(), $dbkey );
635  $this->assertEquals( $title->getNamespace(), $value->getNamespace() );
636  $this->assertEquals( $title->getFragment(), $value->getFragment() );
637  }
638 
639  public static function provideGetFragment() {
640  return [
641  [ 'Foo', '' ],
642  [ 'Foo#bar', 'bar' ],
643  [ 'Foo#bär', 'bär' ],
644 
645  // Inner whitespace is normalized
646  [ 'Foo#bar_bar', 'bar bar' ],
647  [ 'Foo#bar bar', 'bar bar' ],
648  [ 'Foo#bar bar', 'bar bar' ],
649 
650  // Leading whitespace is kept, trailing whitespace is trimmed.
651  // XXX: Is this really want we want?
652  [ 'Foo#_bar_bar_', ' bar bar' ],
653  [ 'Foo# bar bar ', ' bar bar' ],
654  ];
655  }
656 
664  public function testGetFragment( $full, $fragment ) {
665  $title = Title::newFromText( $full );
666  $this->assertEquals( $fragment, $title->getFragment() );
667  }
668 
675  public function testIsAlwaysKnown( $page, $isKnown ) {
676  $title = Title::newFromText( $page );
677  $this->assertEquals( $isKnown, $title->isAlwaysKnown() );
678  }
679 
680  public static function provideIsAlwaysKnown() {
681  return [
682  [ 'Some nonexistent page', false ],
683  [ 'UTPage', false ],
684  [ '#test', true ],
685  [ 'Special:BlankPage', true ],
686  [ 'Special:SomeNonexistentSpecialPage', false ],
687  [ 'MediaWiki:Parentheses', true ],
688  [ 'MediaWiki:Some nonexistent message', false ],
689  ];
690  }
691 
698  public function testIsValid( Title $title, $isValid ) {
699  $this->assertEquals( $isValid, $title->isValid(), $title->getPrefixedText() );
700  }
701 
702  public static function provideIsValid() {
703  return [
704  [ Title::makeTitle( NS_MAIN, '' ), false ],
705  [ Title::makeTitle( NS_MAIN, '<>' ), false ],
706  [ Title::makeTitle( NS_MAIN, '|' ), false ],
707  [ Title::makeTitle( NS_MAIN, '#' ), false ],
708  [ Title::makeTitle( NS_MAIN, 'Test' ), true ],
709  [ Title::makeTitle( -33, 'Test' ), false ],
710  [ Title::makeTitle( 77663399, 'Test' ), false ],
711  ];
712  }
713 
717  public function testIsAlwaysKnownOnInterwiki() {
718  $title = Title::makeTitle( NS_MAIN, 'Interwiki link', '', 'externalwiki' );
719  $this->assertTrue( $title->isAlwaysKnown() );
720  }
721 
725  public function testExists() {
726  $title = Title::makeTitle( NS_PROJECT, 'New page' );
727  $linkCache = MediaWikiServices::getInstance()->getLinkCache();
728 
729  $article = new Article( $title );
730  $page = $article->getPage();
731  $page->doEditContent( new WikitextContent( 'Some [[link]]' ), 'summary' );
732 
733  // Tell Title it doesn't know whether it exists
734  $title->mArticleID = -1;
735 
736  // Tell the link cache it doesn't exists when it really does
737  $linkCache->clearLink( $title );
738  $linkCache->addBadLinkObj( $title );
739 
740  $this->assertEquals(
741  false,
742  $title->exists(),
743  'exists() should rely on link cache unless GAID_FOR_UPDATE is used'
744  );
745  $this->assertEquals(
746  true,
747  $title->exists( Title::GAID_FOR_UPDATE ),
748  'exists() should re-query database when GAID_FOR_UPDATE is used'
749  );
750  }
751 
752  public function provideCanHaveTalkPage() {
753  return [
754  'User page has talk page' => [
755  Title::makeTitle( NS_USER, 'Jane' ), true
756  ],
757  'Talke page has talk page' => [
758  Title::makeTitle( NS_TALK, 'Foo' ), true
759  ],
760  'Special page cannot have talk page' => [
761  Title::makeTitle( NS_SPECIAL, 'Thing' ), false
762  ],
763  'Virtual namespace cannot have talk page' => [
764  Title::makeTitle( NS_MEDIA, 'Kitten.jpg' ), false
765  ],
766  ];
767  }
768 
776  public function testCanHaveTalkPage( Title $title, $expected ) {
777  $actual = $title->canHaveTalkPage();
778  $this->assertSame( $expected, $actual, $title->getPrefixedDBkey() );
779  }
780 
781  public static function provideGetTalkPage_good() {
782  return [
783  [ Title::makeTitle( NS_MAIN, 'Test' ), Title::makeTitle( NS_TALK, 'Test' ) ],
784  [ Title::makeTitle( NS_TALK, 'Test' ), Title::makeTitle( NS_TALK, 'Test' ) ],
785  ];
786  }
787 
792  public function testGetTalkPage_good( Title $title, Title $expected ) {
793  $talk = $title->getTalkPage();
794  $this->assertSame(
795  $expected->getPrefixedDBKey(),
796  $talk->getPrefixedDBKey(),
797  $title->getPrefixedDBKey()
798  );
799  }
800 
806  $talk = $title->getTalkPageIfDefined();
807  $this->assertInstanceOf(
808  Title::class,
809  $talk,
810  $title->getPrefixedDBKey()
811  );
812  }
813 
814  public static function provideGetTalkPage_bad() {
815  return [
816  [ Title::makeTitle( NS_SPECIAL, 'Test' ) ],
817  [ Title::makeTitle( NS_MEDIA, 'Test' ) ],
818  ];
819  }
820 
826  $talk = $title->getTalkPageIfDefined();
827  $this->assertNull(
828  $talk,
829  $title->getPrefixedDBKey()
830  );
831  }
832 
833  public function provideCreateFragmentTitle() {
834  return [
835  [ Title::makeTitle( NS_MAIN, 'Test' ), 'foo' ],
836  [ Title::makeTitle( NS_TALK, 'Test', 'foo' ), '' ],
837  [ Title::makeTitle( NS_CATEGORY, 'Test', 'foo' ), 'bar' ],
838  [ Title::makeTitle( NS_MAIN, 'Test1', '', 'interwiki' ), 'baz' ]
839  ];
840  }
841 
846  public function testCreateFragmentTitle( Title $title, $fragment ) {
847  $this->mergeMwGlobalArrayValue( 'wgHooks', [
848  'InterwikiLoadPrefix' => [
849  function ( $prefix, &$iwdata ) {
850  if ( $prefix === 'interwiki' ) {
851  $iwdata = [
852  'iw_url' => 'http://example.com/',
853  'iw_local' => 0,
854  'iw_trans' => 0,
855  ];
856  return false;
857  }
858  },
859  ],
860  ] );
861 
862  $fragmentTitle = $title->createFragmentTarget( $fragment );
863 
864  $this->assertEquals( $title->getNamespace(), $fragmentTitle->getNamespace() );
865  $this->assertEquals( $title->getText(), $fragmentTitle->getText() );
866  $this->assertEquals( $title->getInterwiki(), $fragmentTitle->getInterwiki() );
867  $this->assertEquals( $fragment, $fragmentTitle->getFragment() );
868  }
869 
870  public function provideGetPrefixedText() {
871  return [
872  // ns = 0
873  [
874  Title::makeTitle( NS_MAIN, 'Foo bar' ),
875  'Foo bar'
876  ],
877  // ns = 2
878  [
879  Title::makeTitle( NS_USER, 'Foo bar' ),
880  'User:Foo bar'
881  ],
882  // ns = 3
883  [
884  Title::makeTitle( NS_USER_TALK, 'Foo bar' ),
885  'User talk:Foo bar'
886  ],
887  // fragment not included
888  [
889  Title::makeTitle( NS_MAIN, 'Foo bar', 'fragment' ),
890  'Foo bar'
891  ],
892  // ns = -2
893  [
894  Title::makeTitle( NS_MEDIA, 'Foo bar' ),
895  'Media:Foo bar'
896  ],
897  // non-existent namespace
898  [
899  Title::makeTitle( 100777, 'Foo bar' ),
900  'Special:Badtitle/NS100777:Foo bar'
901  ],
902  ];
903  }
904 
909  public function testGetPrefixedText( Title $title, $expected ) {
910  $this->assertEquals( $expected, $title->getPrefixedText() );
911  }
912 
913  public function provideGetPrefixedDBKey() {
914  return [
915  // ns = 0
916  [
917  Title::makeTitle( NS_MAIN, 'Foo_bar' ),
918  'Foo_bar'
919  ],
920  // ns = 2
921  [
922  Title::makeTitle( NS_USER, 'Foo_bar' ),
923  'User:Foo_bar'
924  ],
925  // ns = 3
926  [
927  Title::makeTitle( NS_USER_TALK, 'Foo_bar' ),
928  'User_talk:Foo_bar'
929  ],
930  // fragment not included
931  [
932  Title::makeTitle( NS_MAIN, 'Foo_bar', 'fragment' ),
933  'Foo_bar'
934  ],
935  // ns = -2
936  [
937  Title::makeTitle( NS_MEDIA, 'Foo_bar' ),
938  'Media:Foo_bar'
939  ],
940  // non-existent namespace
941  [
942  Title::makeTitle( 100777, 'Foo_bar' ),
943  'Special:Badtitle/NS100777:Foo_bar'
944  ],
945  ];
946  }
947 
952  public function testGetPrefixedDBKey( Title $title, $expected ) {
953  $this->assertEquals( $expected, $title->getPrefixedDBkey() );
954  }
955 
963  public function testGetFragmentForURL( $titleStr, $expected ) {
964  $this->setMwGlobals( [
965  'wgFragmentMode' => [ 'html5' ],
966  'wgExternalInterwikiFragmentMode' => 'legacy',
967  ] );
968  $dbw = wfGetDB( DB_MASTER );
969  $dbw->insert( 'interwiki',
970  [
971  [
972  'iw_prefix' => 'de',
973  'iw_url' => 'http://de.wikipedia.org/wiki/',
974  'iw_api' => 'http://de.wikipedia.org/w/api.php',
975  'iw_wikiid' => 'dewiki',
976  'iw_local' => 1,
977  'iw_trans' => 0,
978  ],
979  [
980  'iw_prefix' => 'zz',
981  'iw_url' => 'http://zzwiki.org/wiki/',
982  'iw_api' => 'http://zzwiki.org/w/api.php',
983  'iw_wikiid' => 'zzwiki',
984  'iw_local' => 0,
985  'iw_trans' => 0,
986  ],
987  ],
988  __METHOD__,
989  [ 'IGNORE' ]
990  );
991 
992  $title = Title::newFromText( $titleStr );
993  self::assertEquals( $expected, $title->getFragmentForURL() );
994 
995  $dbw->delete( 'interwiki', '*', __METHOD__ );
996  }
997 
998  public function provideGetFragmentForURL() {
999  return [
1000  [ 'Foo', '' ],
1001  [ 'Foo#ümlåût', '#ümlåût' ],
1002  [ 'de:Foo#Bå®', '#Bå®' ],
1003  [ 'zz:Foo#тест', '#.D1.82.D0.B5.D1.81.D1.82' ],
1004  ];
1005  }
1006 
1011  public function testIsRawHtmlMessage( $textForm, $expected ) {
1012  $this->setMwGlobals( 'wgRawHtmlMessages', [
1013  'foobar',
1014  'foo_bar',
1015  'foo-bar',
1016  ] );
1017 
1018  $title = Title::newFromText( $textForm );
1019  $this->assertSame( $expected, $title->isRawHtmlMessage() );
1020  }
1021 
1022  public function provideIsRawHtmlMessage() {
1023  return [
1024  [ 'MediaWiki:Foobar', true ],
1025  [ 'MediaWiki:Foo bar', true ],
1026  [ 'MediaWiki:Foo-bar', true ],
1027  [ 'MediaWiki:foo bar', true ],
1028  [ 'MediaWiki:foo-bar', true ],
1029  [ 'MediaWiki:foobar', true ],
1030  [ 'MediaWiki:some-other-message', false ],
1031  [ 'Main Page', false ],
1032  ];
1033  }
1034 
1035  public function provideEquals() {
1036  yield [
1037  Title::newFromText( 'Main Page' ),
1038  Title::newFromText( 'Main Page' ),
1039  true
1040  ];
1041  yield [
1042  Title::newFromText( 'Main Page' ),
1043  Title::newFromText( 'Not The Main Page' ),
1044  false
1045  ];
1046  yield [
1047  Title::newFromText( 'Main Page' ),
1048  Title::newFromText( 'Project:Main Page' ),
1049  false
1050  ];
1051  yield [
1052  Title::newFromText( 'File:Example.png' ),
1053  Title::newFromText( 'Image:Example.png' ),
1054  true
1055  ];
1056  yield [
1057  Title::newFromText( 'Special:Version' ),
1058  Title::newFromText( 'Special:Version' ),
1059  true
1060  ];
1061  yield [
1062  Title::newFromText( 'Special:Version' ),
1063  Title::newFromText( 'Special:Recentchanges' ),
1064  false
1065  ];
1066  yield [
1067  Title::newFromText( 'Special:Version' ),
1068  Title::newFromText( 'Main Page' ),
1069  false
1070  ];
1071  yield [
1072  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1073  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1074  true
1075  ];
1076  yield [
1077  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1078  Title::makeTitle( NS_MAIN, 'Bar', '', '' ),
1079  false
1080  ];
1081  yield [
1082  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1083  Title::makeTitle( NS_TALK, 'Foo', '', '' ),
1084  false
1085  ];
1086  yield [
1087  Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
1088  Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
1089  true
1090  ];
1091  yield [
1092  Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
1093  Title::makeTitle( NS_MAIN, 'Foo', 'Baz', '' ),
1094  true
1095  ];
1096  yield [
1097  Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
1098  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1099  true
1100  ];
1101  yield [
1102  Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
1103  Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
1104  true
1105  ];
1106  yield [
1107  Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
1108  Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
1109  false
1110  ];
1111  }
1112 
1117  public function testEquals( Title $firstValue, /* LinkTarget */ $secondValue, $expectedSame ) {
1118  $this->assertSame(
1119  $expectedSame,
1120  $firstValue->equals( $secondValue )
1121  );
1122  }
1123 
1127  public function testNewMainPage() {
1128  $msgCache = TestingAccessWrapper::newFromClass( MessageCache::class );
1129  $msgCache->instance = $this->createMock( MessageCache::class );
1130  $msgCache->instance->method( 'get' )->willReturn( 'Foresheet' );
1131  $msgCache->instance->method( 'transform' )->willReturn( 'Foresheet' );
1132 
1133  $this->assertSame(
1134  'Foresheet',
1135  Title::newMainPage()->getText()
1136  );
1137  }
1138 
1142  public function testNewMainPageWithLocal() {
1143  $local = $this->createMock( MessageLocalizer::class );
1144  $local->method( 'msg' )->willReturn( new RawMessage( 'Prime Article' ) );
1145 
1146  $this->assertSame(
1147  'Prime Article',
1148  Title::newMainPage( $local )->getText()
1149  );
1150  }
1151 }
The wiki should then use memcached to cache various data To use multiple just add more items to the array To increase the weight of a make its entry a array("192.168.0.1:11211", 2))
getText()
Returns the title in text form, without namespace prefix or fragment.
Definition: TitleValue.php:171
testIsValidMoveOperation( $source, $target, $expected)
Auth-less test of Title::isValidMoveOperation.
Definition: TitleTest.php:296
static castFromLinkTarget( $linkTarget)
Same as newFromLinkTarget, but if passed null, returns null.
Definition: Title.php:295
testSecureAndSplitValid( $text)
See also mediawiki.Title.test.js Title::secureAndSplit provideValidSecureAndSplit.
Definition: TitleTest.php:169
testIsAlwaysKnownOnInterwiki()
Title::isAlwaysKnown.
Definition: TitleTest.php:717
canHaveTalkPage()
Can this title have a corresponding talk page?
Definition: Title.php:1132
$data
Utility to generate mapping file used in mw.Title (phpCharToUpper.json)
static provideGetPageViewLanguage()
Definition: TitleTest.php:449
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
static provideValidSecureAndSplit()
Definition: TitleTest.php:52
testFixSpecialNameRetainsParameter( $text, $expectedParam)
provideSpecialNamesWithAndWithoutParameter Title::fixSpecialName
Definition: TitleTest.php:263
testEquals(Title $firstValue, $secondValue, $expectedSame)
Title::equals provideEquals.
Definition: TitleTest.php:1117
const NS_MAIN
Definition: Defines.php:64
getText()
Get the text form (spaces not underscores) of the main part.
Definition: Title.php:983
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
static newMainPage(MessageLocalizer $localizer=null)
Create a new Title for the Main Page.
Definition: Title.php:653
static provideSpecialNamesWithAndWithoutParameter()
Definition: TitleTest.php:279
testIsAlwaysKnown( $page, $isKnown)
Title::isAlwaysKnown provideIsAlwaysKnown.
Definition: TitleTest.php:675
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
static provideGetFragment()
Definition: TitleTest.php:639
getTalkPageIfDefined()
Get a Title object associated with the talk page of this article, if such a talk page can exist...
Definition: Title.php:1519
if(!isset( $args[0])) $lang
static destroyInstance()
Destroy the singleton instance.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected)
Auth-less test of Title::userCan.
Definition: TitleTest.php:335
Class for viewing MediaWiki article and history.
Definition: Article.php:37
$source
$value
static provideIsValid()
Definition: TitleTest.php:702
const NS_SPECIAL
Definition: Defines.php:53
static provideConvertByteClassToUnicodeClass()
Definition: TitleTest.php:190
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
Definition: injection.txt:23
getPrefixedText()
Get the prefixed title with spaces.
Definition: Title.php:1691
mergeMwGlobalArrayValue( $name, $values)
Merges the given values into a MW global array variable.
secureAndSplitGlobals()
Definition: TitleTest.php:143
testConvertByteClassToUnicodeClass( $byteClass, $unicodeClass)
provideConvertByteClassToUnicodeClass Title::convertByteClassToUnicodeClass
Definition: TitleTest.php:255
static provideRootTitleCases()
Definition: TitleTest.php:520
testGetTalkPage_good(Title $title, Title $expected)
provideGetTalkPage_good Title::getTalkPage
Definition: TitleTest.php:792
testIsValid(Title $title, $isValid)
Title::isValid provideIsValid.
Definition: TitleTest.php:698
const DB_MASTER
Definition: defines.php:26
static provideSubpageTitleCases()
Definition: TitleTest.php:541
static provideNewFromTitleValue()
Definition: TitleTest.php:549
getTalkPage()
Get a Title object associated with the talk page of this article.
Definition: Title.php:1506
testGetRootText( $title, $expected, $msg='')
provideRootTitleCases Title::getRootText
Definition: TitleTest.php:512
getNamespace()
Get the namespace index.
static provideBaseTitleCases()
Definition: TitleTest.php:500
const NEW_CLONE
Flag for use with factory methods like newFromLinkTarget() that have a $forceClone parameter...
Definition: Title.php:64
static provideTestIsValidMoveOperation()
Definition: TitleTest.php:311
provideGetPrefixedText()
Definition: TitleTest.php:870
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message. Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item. Return false to stop further processing of the tag $reader:XMLReader object $logInfo:Array of information 'ImportHandlePageXMLTag':When parsing a XML tag in a page. Return false to stop further processing of the tag $reader:XMLReader object & $pageInfo:Array of information 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision. Return false to stop further processing of the tag $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information 'ImportHandleToplevelXMLTag':When parsing a top level XML tag. Return false to stop further processing of the tag $reader:XMLReader object 'ImportHandleUnknownUser':When a user doesn 't exist locally, this hook is called to give extensions an opportunity to auto-create it. If the auto-creation is successful, return false. $name:User name 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload. Return false to stop further processing of the tag $reader:XMLReader object $revisionInfo:Array of information 'ImportLogInterwikiLink':Hook to change the interwiki link used in log entries and edit summaries for transwiki imports. & $fullInterwikiPrefix:Interwiki prefix, may contain colons. & $pageTitle:String that contains page title. 'ImportSources':Called when reading from the $wgImportSources configuration variable. Can be used to lazy-load the import sources list. & $importSources:The value of $wgImportSources. Modify as necessary. See the comment in DefaultSettings.php for the detail of how to structure this array. 'InfoAction':When building information to display on the action=info page. $context:IContextSource object & $pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect. & $title:Title object for the current page & $request:WebRequest & $ignoreRedirect:boolean to skip redirect check & $target:Title/string of redirect target & $article:Article object 'InternalParseBeforeLinks':during Parser 's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InternalParseBeforeSanitize':during Parser 's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings. Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not. Return true without providing an interwiki to continue interwiki search. $prefix:interwiki prefix we are looking for. & $iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InvalidateEmailComplete':Called after a user 's email has been invalidated successfully. $user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification. Callee may modify $url and $query, URL will be constructed as $url . $query & $url:URL to index.php & $query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) & $article:article(object) being checked 'IsTrustedProxy':Override the result of IP::isTrustedProxy() & $ip:IP being check & $result:Change this value to override the result of IP::isTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from & $allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of Sanitizer::validateEmail(), for instance to return false if the domain name doesn 't match your organization. $addr:The e-mail address entered by the user & $result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user & $result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we 're looking for a messages file for & $file:The messages file path, you can override this to change the location. 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces. Do not use this hook to add namespaces. Use CanonicalNamespaces for that. & $namespaces:Array of namespaces indexed by their numbers 'LanguageGetTranslatedLanguageNames':Provide translated language names. & $names:array of language code=> language name $code:language of the preferred translations 'LanguageLinks':Manipulate a page 's language links. This is called in various places to allow extensions to define the effective language links for a page. $title:The page 's Title. & $links:Array with elements of the form "language:title" in the order that they will be output. & $linkFlags:Associative array mapping prefixed links to arrays of flags. Currently unused, but planned to provide support for marking individual language links in the UI, e.g. for featured articles. 'LanguageSelector':Hook to change the language selector available on a page. $out:The output page. $cssClassName:CSS class name of the language selector. 'LinkBegin':DEPRECATED since 1.28! Use HtmlPageLinkRendererBegin instead. Used when generating internal and interwiki links in Linker::link(), before processing starts. Return false to skip default processing and return $ret. See documentation for Linker::link() for details on the expected meanings of parameters. $skin:the Skin object $target:the Title that the link is pointing to & $html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1980
static convertByteClassToUnicodeClass( $byteClass)
Utility method for converting a character sequence from bytes to Unicode.
Definition: Title.php:714
getFragment()
Get the link fragment (i.e.
testGetPrefixedDBKey(Title $title, $expected)
Title::getPrefixedDBKey provideGetPrefixedDBKey.
Definition: TitleTest.php:952
testGetBaseText( $title, $expected, $msg='')
provideBaseTitleCases Title::getBaseText
Definition: TitleTest.php:492
testExists()
Title::exists.
Definition: TitleTest.php:725
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
Definition: hooks.txt:1982
testGetFragmentForURL( $titleStr, $expected)
Title::getFragmentForURL provideGetFragmentForURL.
Definition: TitleTest.php:963
Database Title.
Definition: TitleTest.php:11
const NS_PROJECT
Definition: Defines.php:68
testNewMainPageWithLocal()
Title::newMainPage.
Definition: TitleTest.php:1142
testGetTalkPageIfDefined_bad(Title $title)
provideGetTalkPage_bad Title::getTalkPageIfDefined
Definition: TitleTest.php:825
const NS_MEDIA
Definition: Defines.php:52
const GAID_FOR_UPDATE
Used to be GAID_FOR_UPDATE define.
Definition: Title.php:55
flattenErrorsArray( $errors)
Definition: TitleTest.php:415
const NS_CATEGORY
Definition: Defines.php:78
dataWgWhitelistReadRegexp()
Provides test parameter values for testWgWhitelistReadRegexp()
Definition: TitleTest.php:379
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not null
Definition: hooks.txt:780
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:925
getNamespace()
Get the namespace index, i.e.
Definition: Title.php:1025
provideCreateFragmentTitle()
Definition: TitleTest.php:833
equals(Title $title)
Compare with another title.
Definition: Title.php:4037
testLegalChars()
Title::legalChars.
Definition: TitleTest.php:33
overrideMwServices(Config $configOverrides=null, array $services=[])
Stashes the global instance of MediaWikiServices, and installs a new one, allowing test cases to over...
getInterwiki()
Get the interwiki prefix.
Definition: Title.php:911
setMwGlobals( $pairs, $value=null)
Sets a global, maintaining a stashed version of the previous global to be restored in tearDown...
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
static provideInvalidSecureAndSplit()
Definition: TitleTest.php:89
provideIsRawHtmlMessage()
Definition: TitleTest.php:1022
testSecureAndSplitInvalid( $text, $expectedErrorMessage)
See also mediawiki.Title.test.js Title::secureAndSplit provideInvalidSecureAndSplit.
Definition: TitleTest.php:180
static newFromTextThrow( $text, $defaultNamespace=NS_MAIN)
Like Title::newFromText(), but throws MalformedTitleException when the title is invalid, rather than returning null.
Definition: Title.php:356
isValid()
Returns true if the title is valid, false if it is invalid.
Definition: Title.php:864
static provideIsAlwaysKnown()
Definition: TitleTest.php:680
testGetPrefixedText(Title $title, $expected)
Title::getPrefixedText provideGetPrefixedText.
Definition: TitleTest.php:909
testCreateFragmentTitle(Title $title, $fragment)
Title::createFragmentTarget provideCreateFragmentTitle.
Definition: TitleTest.php:846
static newFromLinkTarget(LinkTarget $linkTarget, $forceClone='')
Returns a Title given a LinkTarget.
Definition: Title.php:271
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:589
provideGetFragmentForURL()
Definition: TitleTest.php:998
testCanHaveTalkPage(Title $title, $expected)
provideCanHaveTalkPage Title::canHaveTalkPage
Definition: TitleTest.php:776
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
provideGetPrefixedDBKey()
Definition: TitleTest.php:913
static newFromDBkey( $key)
Create a new Title from a prefixed DB key.
Definition: Title.php:231
static provideGetTalkPage_bad()
Definition: TitleTest.php:814
createFragmentTarget( $fragment)
Creates a new Title for a different fragment of the same page.
Definition: Title.php:1637
provideCastFromLinkTarget()
Definition: TitleTest.php:596
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
Variant of the Message class.
Definition: RawMessage.php:34
testIsRawHtmlMessage( $textForm, $expected)
Title::isRawHtmlMessage provideIsRawHtmlMessage.
Definition: TitleTest.php:1011
provideCanHaveTalkPage()
Definition: TitleTest.php:752
static provideGetTitleValue()
Definition: TitleTest.php:617
testGetSubpageText( $title, $expected, $msg='')
Definition: TitleTest.php:533
testGetTitleValue( $text)
Title::getTitleValue provideGetTitleValue.
Definition: TitleTest.php:629
getText()
Returns the link in text form, without namespace prefix or fragment.
static provideGetTalkPage_good()
Definition: TitleTest.php:781
static legalChars()
Get a regex character class describing the legal characters in a link.
Definition: Title.php:700
const NS_TALK
Definition: Defines.php:65
testGetFragment( $full, $fragment)
Title::getFragment provideGetFragment.
Definition: TitleTest.php:664
testGetPageViewLanguage( $expected, $titleText, $contLang, $lang, $variant, $msg='')
provideGetPageViewLanguage Title::getPageViewLanguage
Definition: TitleTest.php:428
testNewFromLinkTarget_clone()
Title::newFromLinkTarget.
Definition: TitleTest.php:586
return true to allow those checks to and false if checking is done remove or add to the links of a group of changes in EnhancedChangesList Hook subscribers can return false to omit this line from recentchanges use this to change the tables headers change it to an object instance and return false override the list derivative used the name of the old file & $article
Definition: hooks.txt:1473
testNewMainPage()
Title::newMainPage.
Definition: TitleTest.php:1127
const NS_USER_TALK
Definition: Defines.php:67
testGetTalkPageIfDefined_good(Title $title)
provideGetTalkPage_good Title::getTalkPageIfDefined
Definition: TitleTest.php:805
static newFromTitleValue(TitleValue $titleValue, $forceClone='')
Returns a Title given a TitleValue.
Definition: Title.php:256
testNewFromLinkTarget(LinkTarget $value)
Title::newFromLinkTarget provideNewFromTitleValue.
Definition: TitleTest.php:574
testCastFromLinkTarget( $value)
Title::castFromLinkTarget provideCastFromLinkTarget.
Definition: TitleTest.php:604
return true to allow those checks to and false if checking is done & $user
Definition: hooks.txt:1473
getPrefixedDBkey()
Get the prefixed database key form.
Definition: Title.php:1679
testNewFromTitleValue(TitleValue $value)
Title::newFromTitleValue provideNewFromTitleValue.
Definition: TitleTest.php:561
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:319