ILIAS  release_8 Revision v8.24
Title.php
Go to the documentation of this file.
1<?php
2
3// patched: alex, 30.4.2019: Added missing defines
4
5define('NS_MAIN', "nsmain");
6define('NS_SPECIAL', "nsspecial");
7
8define('GAID_FOR_UPDATE', 1);
9
10# Title::newFromTitle maintains a cache to avoid
11# expensive re-normalization of commonly used titles.
12# On a batch operation this can become a memory leak
13# if not bounded. After hitting this many titles,
14# reset the cache.
15define('MW_TITLECACHE_MAX', 1000);
16
17# Constants for pr_cascade bitfield
18define('CASCADE', 1);
19
26class Title
27{
31 private static $titleCache = array();
32 private static $interwikiCache = array();
33
34
44 public $mTextform; # Text form (spaces not underscores) of the main part
45 public $mUrlform; # URL-encoded form of the main part
46 public $mDbkeyform; # Main part with underscores
47 public $mNamespace; # Namespace index, i.e. one of the NS_xxxx constants
48 public $mInterwiki; # Interwiki prefix (or null string)
49 public $mFragment; # Title fragment (i.e. the bit after the #)
50 public $mArticleID; # Article ID, fetched from the link cache on demand
51 public $mLatestID; # ID of most recent revision
52 public $mRestrictions; # Array of groups allowed to edit this article
53 public $mCascadeRestriction; # Cascade restrictions on this page to included templates and images?
54 public $mRestrictionsExpiry; # When do the restrictions on this page expire?
55 public $mHasCascadingRestrictions; # Are cascading restrictions in effect on this page?
56 public $mCascadeRestrictionSources;# Where are the cascading restrictions coming from on this page?
57 public $mRestrictionsLoaded; # Boolean for initialisation on demand
58 public $mPrefixedText; # Text form including namespace/interwiki, initialised on demand
59 public $mDefaultNamespace; # Namespace index when there is no namespace
60 # Zero except in {{transclusion}} tags
61 public $mWatched; # Is $wgUser watching this page? NULL if unfilled, accessed through userIsWatching()
69 /* private */ public function __construct()
70 {
71 $this->mInterwiki = $this->mUrlform =
72 $this->mTextform = $this->mDbkeyform = '';
73 $this->mArticleID = -1;
74 $this->mNamespace = NS_MAIN;
75 $this->mRestrictionsLoaded = false;
76 $this->mRestrictions = array();
77 # Dont change the following, NS_MAIN is hardcoded in several place
78 # See bug #696
79 $this->mDefaultNamespace = NS_MAIN;
80 $this->mWatched = null;
81 $this->mLatestID = false;
82 $this->mOldRestrictions = false;
83 }
84
92 public static function newFromDBkey($key)
93 {
94 $t = new Title();
95 $t->mDbkeyform = $key;
96 if ($t->secureAndSplit()) {
97 return $t;
98 } else {
99 return null;
100 }
101 }
102
114 public static function newFromText($text, $defaultNamespace = NS_MAIN)
115 {
116 if (is_object($text)) {
117 throw new MWException('Title::newFromText given an object');
118 }
119
128 if ($defaultNamespace == NS_MAIN && isset(Title::$titleCache[$text])) {
129 return Title::$titleCache[$text];
130 }
131
135 $filteredText = Sanitizer::decodeCharReferences($text);
136
137 $t = new Title();
138 $t->mDbkeyform = str_replace(' ', '_', $filteredText);
139 $t->mDefaultNamespace = $defaultNamespace;
140
141 static $cachedcount = 0 ;
142 if ($t->secureAndSplit()) {
143 if ($defaultNamespace == NS_MAIN) {
144 if ($cachedcount >= MW_TITLECACHE_MAX) {
145 # Avoid memory leaks on mass operations...
146 Title::$titleCache = array();
147 $cachedcount = 0;
148 }
149 $cachedcount++;
150 Title::$titleCache[$text] = &$t;
151 }
152 return $t;
153 } else {
154 $ret = null;
155 return $ret;
156 }
157 }
158
165 public static function newFromURL($url)
166 {
167 global $wgLegalTitleChars;
168 $t = new Title();
169
170 # For compatibility with old buggy URLs. "+" is usually not valid in titles,
171 # but some URLs used it as a space replacement and they still come
172 # from some external search tools.
173 if (strpos($wgLegalTitleChars, '+') === false) {
174 $url = str_replace('+', ' ', $url);
175 }
176
177 $t->mDbkeyform = str_replace(' ', '_', $url);
178 if ($t->secureAndSplit()) {
179 return $t;
180 } else {
181 return null;
182 }
183 }
184
194 public static function newFromID($id)
195 {
196 $fname = 'Title::newFromID';
197 $dbr = wfGetDB(DB_SLAVE);
198 $row = $dbr->selectRow(
199 'page',
200 array( 'page_namespace', 'page_title' ),
201 array( 'page_id' => $id ),
202 $fname
203 );
204 if ($row !== false) {
205 $title = Title::makeTitle($row->page_namespace, $row->page_title);
206 } else {
207 $title = null;
208 }
209 return $title;
210 }
211
215 public static function newFromIDs($ids)
216 {
217 $dbr = wfGetDB(DB_SLAVE);
218 $res = $dbr->select(
219 'page',
220 array( 'page_namespace', 'page_title' ),
221 'page_id IN (' . $dbr->makeList($ids) . ')',
222 __METHOD__
223 );
224
225 $titles = array();
226 while ($row = $dbr->fetchObject($res)) {
227 $titles[] = Title::makeTitle($row->page_namespace, $row->page_title);
228 }
229 return $titles;
230 }
231
243 public static function &makeTitle($ns, $title)
244 {
245 $t = new Title();
246 $t->mInterwiki = '';
247 $t->mFragment = '';
248 $t->mNamespace = intval($ns);
249 $t->mDbkeyform = str_replace(' ', '_', $title);
250 $t->mArticleID = ($ns >= 0) ? -1 : 0;
251 $t->mUrlform = wfUrlencode($t->mDbkeyform);
252 $t->mTextform = str_replace('_', ' ', $title);
253 return $t;
254 }
255
265 public static function makeTitleSafe($ns, $title)
266 {
267 $t = new Title();
268 $t->mDbkeyform = Title::makeName($ns, $title);
269 if ($t->secureAndSplit()) {
270 return $t;
271 } else {
272 return null;
273 }
274 }
275
280 public static function newMainPage()
281 {
282 return Title::newFromText(wfMsgForContent('mainpage'));
283 }
284
285
286 #----------------------------------------------------------------------------
287 # Static functions
288 #----------------------------------------------------------------------------
289
298 public function nameOf($id)
299 {
300 $fname = 'Title::nameOf';
301 $dbr = wfGetDB(DB_SLAVE);
302
303 $s = $dbr->selectRow('page', array( 'page_namespace','page_title' ), array( 'page_id' => $id ), $fname);
304 if ($s === false) {
305 return null;
306 }
307
308 $n = Title::makeName($s->page_namespace, $s->page_title);
309 return $n;
310 }
311
316 public static function legalChars()
317 {
318 global $wgLegalTitleChars;
319
320 $wgLegalTitleChars = " %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+";
321
322 return $wgLegalTitleChars;
323 }
324
325
326 /*
327 * Make a prefixed DB key from a DB key and a namespace index
328 * @param int $ns numerical representation of the namespace
329 * @param string $title the DB key form the title
330 * @return string the prefixed form of the title
331 */
332 public static function makeName($ns, $title)
333 {
334 global $wgContLang;
335
336 $n = $wgContLang->getNsText($ns);
337 return $n == '' ? $title : "$n:$title";
338 }
339
347 public function getInterwikiLink($key)
348 {
349 global $wgMemc, $wgInterwikiExpiry;
350 global $wgInterwikiCache, $wgContLang;
351
352 return ""; // changed. alex
353
354 $fname = 'Title::getInterwikiLink';
355
356 $key = $wgContLang->lc($key);
357
358 $k = wfMemcKey('interwiki', $key);
359 if (array_key_exists($k, Title::$interwikiCache)) {
360 return Title::$interwikiCache[$k]->iw_url;
361 }
362
363 if ($wgInterwikiCache) {
365 }
366
367 $s = $wgMemc->get($k);
368 # Ignore old keys with no iw_local
369 if ($s && isset($s->iw_local) && isset($s->iw_trans)) {
370 Title::$interwikiCache[$k] = $s;
371 return $s->iw_url;
372 }
373
374 $dbr = wfGetDB(DB_SLAVE);
375 $res = $dbr->select(
376 'interwiki',
377 array( 'iw_url', 'iw_local', 'iw_trans' ),
378 array( 'iw_prefix' => $key ),
379 $fname
380 );
381 if (!$res) {
382 return '';
383 }
384
385 $s = $dbr->fetchObject($res);
386 if (!$s) {
387 # Cache non-existence: create a blank object and save it to memcached
388 $s = (object) false;
389 $s->iw_url = '';
390 $s->iw_local = 0;
391 $s->iw_trans = 0;
392 }
393 $wgMemc->set($k, $s, $wgInterwikiExpiry);
394 Title::$interwikiCache[$k] = $s;
395
396 return $s->iw_url;
397 }
398
406 public static function getInterwikiCached($key)
407 {
408 global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite;
409 static $db, $site;
410
411 if (!$db) {
412 $db = dba_open($wgInterwikiCache, 'r', 'cdb');
413 }
414 /* Resolve site name */
415 if ($wgInterwikiScopes >= 3 and !$site) {
416 $site = dba_fetch('__sites:' . wfWikiID(), $db);
417 if ($site == "") {
418 $site = $wgInterwikiFallbackSite;
419 }
420 }
421 $value = dba_fetch(wfMemcKey($key), $db);
422 if ($value == '' and $wgInterwikiScopes >= 3) {
423 /* try site-level */
424 $value = dba_fetch("_{$site}:{$key}", $db);
425 }
426 if ($value == '' and $wgInterwikiScopes >= 2) {
427 /* try globals */
428 $value = dba_fetch("__global:{$key}", $db);
429 }
430 if ($value == 'undef') {
431 $value = '';
432 }
433 $s = (object) false;
434 $s->iw_url = '';
435 $s->iw_local = 0;
436 $s->iw_trans = 0;
437 if ($value != '') {
438 list($local, $url) = explode(' ', $value, 2);
439 $s->iw_url = $url;
440 $s->iw_local = (int) $local;
441 }
442 Title::$interwikiCache[wfMemcKey('interwiki', $key)] = $s;
443 return $s->iw_url;
444 }
452 public function isLocal()
453 {
454 if ($this->mInterwiki != '') {
455 # Make sure key is loaded into cache
456 $this->getInterwikiLink($this->mInterwiki);
457 $k = wfMemcKey('interwiki', $this->mInterwiki);
458 return (bool) (Title::$interwikiCache[$k]->iw_local);
459 } else {
460 return true;
461 }
462 }
463
470 public function isTrans()
471 {
472 if ($this->mInterwiki == '') {
473 return false;
474 }
475 # Make sure key is loaded into cache
476 $this->getInterwikiLink($this->mInterwiki);
477 $k = wfMemcKey('interwiki', $this->mInterwiki);
478 return (bool) (Title::$interwikiCache[$k]->iw_trans);
479 }
480
484 public static function escapeFragmentForURL($fragment)
485 {
486 $fragment = str_replace(' ', '_', $fragment);
487 $fragment = urlencode(Sanitizer::decodeCharReferences($fragment));
488 $replaceArray = array(
489 '%3A' => ':',
490 '%' => '.'
491 );
492 return strtr($fragment, $replaceArray);
493 }
494
495 #----------------------------------------------------------------------------
496 # Other stuff
497 #----------------------------------------------------------------------------
498
504 public function getText()
505 {
506 return $this->mTextform;
507 }
512 public function getPartialURL()
513 {
514 return $this->mUrlform;
515 }
520 public function getDBkey()
521 {
522 return $this->mDbkeyform;
523 }
528 public function getNamespace()
529 {
530 return $this->mNamespace;
531 }
536 public function getNsText()
537 {
538 global $wgContLang, $wgCanonicalNamespaceNames;
539
540 if ('' != $this->mInterwiki) {
541 // This probably shouldn't even happen. ohh man, oh yuck.
542 // But for interwiki transclusion it sometimes does.
543 // Shit. Shit shit shit.
544 //
545 // Use the canonical namespaces if possible to try to
546 // resolve a foreign namespace.
547 if (isset($wgCanonicalNamespaceNames[$this->mNamespace])) {
548 return $wgCanonicalNamespaceNames[$this->mNamespace];
549 }
550 }
551 return $wgContLang->getNsText($this->mNamespace);
552 }
557 /* public function getSubjectNsText() {
558 global $wgContLang;
559 return $wgContLang->getNsText( Namespace::getSubject( $this->mNamespace ) );
560 }*/
561
566 /* public function getTalkNsText() {
567 global $wgContLang;
568 return( $wgContLang->getNsText( Namespace::getTalk( $this->mNamespace ) ) );
569 }*/
570
575 /* public function canTalk() {
576 return( Namespace::canTalk( $this->mNamespace ) );
577 }*/
578
583 public function getInterwiki()
584 {
585 return $this->mInterwiki;
586 }
591 public function getFragment()
592 {
593 return $this->mFragment;
594 }
599 public function getFragmentForURL()
600 {
601 if ($this->mFragment == '') {
602 return '';
603 } else {
604 return '#' . Title::escapeFragmentForURL($this->mFragment);
605 }
606 }
611 public function getDefaultNamespace()
612 {
614 }
615
621 public function getIndexTitle()
622 {
623 return Title::indexTitle($this->mNamespace, $this->mTextform);
624 }
625
631 public function getPrefixedDBkey()
632 {
633 $s = $this->prefix($this->mDbkeyform);
634 $s = str_replace(' ', '_', $s);
635 return $s;
636 }
637
643 public function getPrefixedText()
644 {
645 if (empty($this->mPrefixedText)) { // FIXME: bad usage of empty() ?
646 $s = $this->prefix($this->mTextform);
647 $s = str_replace('_', ' ', $s);
648 $this->mPrefixedText = $s;
649 }
651 }
652
659 public function getFullText()
660 {
661 $text = $this->getPrefixedText();
662 if ('' != $this->mFragment) {
663 $text .= '#' . $this->mFragment;
664 }
665 return $text;
666 }
667
672 public function getBaseText()
673 {
674 global $wgNamespacesWithSubpages;
675 if (isset($wgNamespacesWithSubpages[ $this->mNamespace ]) && $wgNamespacesWithSubpages[ $this->mNamespace ]) {
676 $parts = explode('/', $this->getText());
677 # Don't discard the real title if there's no subpage involved
678 if (count($parts) > 1) {
679 unset($parts[ count($parts) - 1 ]);
680 }
681 return implode('/', $parts);
682 } else {
683 return $this->getText();
684 }
685 }
686
691 public function getSubpageText()
692 {
693 global $wgNamespacesWithSubpages;
694 if (isset($wgNamespacesWithSubpages[ $this->mNamespace ]) && $wgNamespacesWithSubpages[ $this->mNamespace ]) {
695 $parts = explode('/', $this->mTextform);
696 return($parts[ count($parts) - 1 ]);
697 } else {
698 return($this->mTextform);
699 }
700 }
701
706 public function getSubpageUrlForm()
707 {
708 $text = $this->getSubpageText();
709 $text = wfUrlencode(str_replace(' ', '_', $text));
710 $text = str_replace('%28', '(', str_replace('%29', ')', $text)); # Clean up the URL; per below, this might not be safe
711 return($text);
712 }
713
718 public function getPrefixedURL()
719 {
720 $s = $this->prefix($this->mDbkeyform);
721 $s = str_replace(' ', '_', $s);
722
723 $s = wfUrlencode($s) ;
724
725 # Cleaning up URL to make it look nice -- is this safe?
726 $s = str_replace('%28', '(', $s);
727 $s = str_replace('%29', ')', $s);
728
729 return $s;
730 }
731
741 public function getFullURL($query = '', $variant = false)
742 {
743 global $wgContLang, $wgServer, $wgRequest;
744
745 if ('' == $this->mInterwiki) {
746 $url = $this->getLocalURL($query, $variant);
747
748 // Ugly quick hack to avoid duplicate prefixes (bug 4571 etc)
749 // Correct fix would be to move the prepending elsewhere.
750 if ($wgRequest->getVal('action') != 'render') {
751 $url = $wgServer . $url;
752 }
753 } else {
754 $baseUrl = $this->getInterwikiLink($this->mInterwiki);
755
756 $namespace = wfUrlencode($this->getNsText());
757 if ('' != $namespace) {
758 # Can this actually happen? Interwikis shouldn't be parsed.
759 # Yes! It can in interwiki transclusion. But... it probably shouldn't.
760 $namespace .= ':';
761 }
762 $url = str_replace('$1', $namespace . $this->mUrlform, $baseUrl);
763 $url = wfAppendQuery($url, $query);
764 }
765
766 # Finally, add the fragment.
767 $url .= $this->getFragmentForURL();
768
769 wfRunHooks('GetFullURL', array( &$this, &$url, $query ));
770 return $url;
771 }
772
781 public function getLocalURL($query = '', $variant = false)
782 {
783 global $wgArticlePath, $wgScript, $wgServer, $wgRequest;
784 global $wgVariantArticlePath, $wgContLang, $wgUser;
785
786 // internal links should point to same variant as current page (only anonymous users)
787 if ($variant == false && $wgContLang->hasVariants() && !$wgUser->isLoggedIn()) {
788 $pref = $wgContLang->getPreferredVariant(false);
789 if ($pref != $wgContLang->getCode()) {
790 $variant = $pref;
791 }
792 }
793
794 if ($this->isExternal()) {
795 $url = $this->getFullURL();
796 if ($query) {
797 // This is currently only used for edit section links in the
798 // context of interwiki transclusion. In theory we should
799 // append the query to the end of any existing query string,
800 // but interwiki transclusion is already broken in that case.
801 $url .= "?$query";
802 }
803 } else {
804 $dbkey = wfUrlencode($this->getPrefixedDBkey());
805 if ($query == '') {
806 if ($variant != false && $wgContLang->hasVariants()) {
807 if ($wgVariantArticlePath == false) {
808 $variantArticlePath = "$wgScript?title=$1&variant=$2"; // default
809 } else {
810 $variantArticlePath = $wgVariantArticlePath;
811 }
812 $url = str_replace('$2', urlencode($variant), $variantArticlePath);
813 $url = str_replace('$1', $dbkey, $url);
814 } else {
815 $url = str_replace('$1', $dbkey, $wgArticlePath);
816 }
817 } else {
818 global $wgActionPaths;
819 $url = false;
820 $matches = array();
821 if (!empty($wgActionPaths) &&
822 preg_match('/^(.*&|)action=([^&]*)(&(.*)|)$/', $query, $matches)) {
823 $action = urldecode($matches[2]);
824 if (isset($wgActionPaths[$action])) {
825 $query = $matches[1];
826 if (isset($matches[4])) {
827 $query .= $matches[4];
828 }
829 $url = str_replace('$1', $dbkey, $wgActionPaths[$action]);
830 if ($query != '') {
831 $url .= '?' . $query;
832 }
833 }
834 }
835 if ($url === false) {
836 if ($query == '-') {
837 $query = '';
838 }
839 $url = "{$wgScript}?title={$dbkey}&{$query}";
840 }
841 }
842
843 // FIXME: this causes breakage in various places when we
844 // actually expected a local URL and end up with dupe prefixes.
845 if ($wgRequest->getVal('action') == 'render') {
846 $url = $wgServer . $url;
847 }
848 }
849 wfRunHooks('GetLocalURL', array( &$this, &$url, $query ));
850 return $url;
851 }
852
859 public function escapeLocalURL($query = '')
860 {
861 return htmlspecialchars($this->getLocalURL($query));
862 }
863
871 public function escapeFullURL($query = '')
872 {
873 return htmlspecialchars($this->getFullURL($query));
874 }
875
885 public function getInternalURL($query = '', $variant = false)
886 {
887 global $wgInternalServer;
888 $url = $wgInternalServer . $this->getLocalURL($query, $variant);
889 wfRunHooks('GetInternalURL', array( &$this, &$url, $query ));
890 return $url;
891 }
892
898 public function getEditURL()
899 {
900 if ('' != $this->mInterwiki) {
901 return '';
902 }
903 $s = $this->getLocalURL('action=edit');
904
905 return $s;
906 }
907
913 public function getEscapedText()
914 {
915 return htmlspecialchars($this->getPrefixedText());
916 }
917
922 public function isExternal()
923 {
924 return ('' != $this->mInterwiki);
925 }
926
933 public function isSemiProtected($action = 'edit')
934 {
935 if ($this->exists()) {
936 $restrictions = $this->getRestrictions($action);
937 if (count($restrictions) > 0) {
938 foreach ($restrictions as $restriction) {
939 if (strtolower($restriction) != 'autoconfirmed') {
940 return false;
941 }
942 }
943 } else {
944 # Not protected
945 return false;
946 }
947 return true;
948 } else {
949 # If it doesn't exist, it can't be protected
950 return false;
951 }
952 }
953
960 public function isProtected($action = '')
961 {
962 global $wgRestrictionLevels;
963
964 # Special pages have inherent protection
965 if ($this->getNamespace() == NS_SPECIAL) {
966 return true;
967 }
968
969 # Check regular protection levels
970 if ($action == 'edit' || $action == '') {
971 $r = $this->getRestrictions('edit');
972 foreach ($wgRestrictionLevels as $level) {
973 if (in_array($level, $r) && $level != '') {
974 return(true);
975 }
976 }
977 }
978
979 if ($action == 'move' || $action == '') {
980 $r = $this->getRestrictions('move');
981 foreach ($wgRestrictionLevels as $level) {
982 if (in_array($level, $r) && $level != '') {
983 return(true);
984 }
985 }
986 }
987
988 return false;
989 }
990
995 public function userIsWatching()
996 {
997 global $wgUser;
998
999 if (is_null($this->mWatched)) {
1000 if (NS_SPECIAL == $this->mNamespace || !$wgUser->isLoggedIn()) {
1001 $this->mWatched = false;
1002 } else {
1003 $this->mWatched = $wgUser->isWatched($this);
1004 }
1005 }
1006 return $this->mWatched;
1007 }
1008
1018 public function quickUserCan($action)
1019 {
1020 return $this->userCan($action, false);
1021 }
1022
1029 public function userCan($action, $doExpensiveQueries = true)
1030 {
1031 $fname = 'Title::userCan';
1032 wfProfileIn($fname);
1033
1034 global $wgUser, $wgNamespaceProtection;
1035
1036 $result = null;
1037 wfRunHooks('userCan', array( &$this, &$wgUser, $action, &$result ));
1038 if ($result !== null) {
1039 wfProfileOut($fname);
1040 return $result;
1041 }
1042
1043 if (NS_SPECIAL == $this->mNamespace) {
1044 wfProfileOut($fname);
1045 return false;
1046 }
1047
1048 if (array_key_exists($this->mNamespace, $wgNamespaceProtection)) {
1049 $nsProt = $wgNamespaceProtection[ $this->mNamespace ];
1050 if (!is_array($nsProt)) {
1051 $nsProt = array($nsProt);
1052 }
1053 foreach ($nsProt as $right) {
1054 if ('' != $right && !$wgUser->isAllowed($right)) {
1055 wfProfileOut($fname);
1056 return false;
1057 }
1058 }
1059 }
1060
1061 if ($this->mDbkeyform == '_') {
1062 # FIXME: Is this necessary? Shouldn't be allowed anyway...
1063 wfProfileOut($fname);
1064 return false;
1065 }
1066
1067 # protect css/js subpages of user pages
1068 # XXX: this might be better using restrictions
1069 # XXX: Find a way to work around the php bug that prevents using $this->userCanEditCssJsSubpage() from working
1070 if ($this->isCssJsSubpage()
1071 && !$wgUser->isAllowed('editinterface')
1072 && !preg_match('/^' . preg_quote($wgUser->getName(), '/') . '\//', $this->mTextform)) {
1073 wfProfileOut($fname);
1074 return false;
1075 }
1076
1077 if ($doExpensiveQueries && !$this->isCssJsSubpage()) {
1078 # We /could/ use the protection level on the source page, but it's fairly ugly
1079 # as we have to establish a precedence hierarchy for pages included by multiple
1080 # cascade-protected pages. So just restrict it to people with 'protect' permission,
1081 # as they could remove the protection anyway.
1082 list($cascadingSources, $restrictions) = $this->getCascadeProtectionSources();
1083 # Cascading protection depends on more than this page...
1084 # Several cascading protected pages may include this page...
1085 # Check each cascading level
1086 # This is only for protection restrictions, not for all actions
1087 if ($cascadingSources > 0 && isset($restrictions[$action])) {
1088 foreach ($restrictions[$action] as $right) {
1089 $right = ($right == 'sysop') ? 'protect' : $right;
1090 if ('' != $right && !$wgUser->isAllowed($right)) {
1091 wfProfileOut($fname);
1092 return false;
1093 }
1094 }
1095 }
1096 }
1097
1098 foreach ($this->getRestrictions($action) as $right) {
1099 // Backwards compatibility, rewrite sysop -> protect
1100 if ($right == 'sysop') {
1101 $right = 'protect';
1102 }
1103 if ('' != $right && !$wgUser->isAllowed($right)) {
1104 wfProfileOut($fname);
1105 return false;
1106 }
1107 }
1108
1109 if ($action == 'move' &&
1110 !($this->isMovable() && $wgUser->isAllowed('move'))) {
1111 wfProfileOut($fname);
1112 return false;
1113 }
1114
1115 if ($action == 'create') {
1116 if (($this->isTalkPage() && !$wgUser->isAllowed('createtalk')) ||
1117 (!$this->isTalkPage() && !$wgUser->isAllowed('createpage'))) {
1118 wfProfileOut($fname);
1119 return false;
1120 }
1121 }
1122
1123 wfProfileOut($fname);
1124 return true;
1125 }
1126
1132 public function userCanEdit($doExpensiveQueries = true)
1133 {
1134 return $this->userCan('edit', $doExpensiveQueries);
1135 }
1136
1142 public function userCanCreate($doExpensiveQueries = true)
1143 {
1144 return $this->userCan('create', $doExpensiveQueries);
1145 }
1146
1152 public function userCanMove($doExpensiveQueries = true)
1153 {
1154 return $this->userCan('move', $doExpensiveQueries);
1155 }
1156
1163 /* public function isMovable() {
1164 return Namespace::isMovable( $this->getNamespace() )
1165 && $this->getInterwiki() == '';
1166 }*/
1167
1173 public function userCanRead()
1174 {
1175 global $wgUser;
1176
1177 $result = null;
1178 wfRunHooks('userCan', array( &$this, &$wgUser, 'read', &$result ));
1179 if ($result !== null) {
1180 return $result;
1181 }
1182
1183 if ($wgUser->isAllowed('read')) {
1184 return true;
1185 } else {
1186 global $wgWhitelistRead;
1187
1192 if ($this->isSpecial('Userlogin') || $this->isSpecial('Resetpass')) {
1193 return true;
1194 }
1195
1197 $name = $this->getPrefixedText();
1198 if ($wgWhitelistRead && in_array($name, $wgWhitelistRead)) {
1199 return true;
1200 }
1201
1202 # Compatibility with old settings
1203 if ($wgWhitelistRead && $this->getNamespace() == NS_MAIN) {
1204 if (in_array(':' . $name, $wgWhitelistRead)) {
1205 return true;
1206 }
1207 }
1208 }
1209 return false;
1210 }
1211
1216 /* public function isTalkPage() {
1217 return Namespace::isTalk( $this->getNamespace() );
1218 }*/
1219
1224 public function isSubpage()
1225 {
1226 global $wgNamespacesWithSubpages;
1227
1228 if (isset($wgNamespacesWithSubpages[ $this->mNamespace ])) {
1229 return (strpos($this->getText(), '/') !== false && $wgNamespacesWithSubpages[ $this->mNamespace ] == true);
1230 } else {
1231 return false;
1232 }
1233 }
1234
1238 public function getSkinFromCssJsSubpage()
1239 {
1240 $subpage = explode('/', $this->mTextform);
1241 $subpage = $subpage[ count($subpage) - 1 ];
1242 return(str_replace(array( '.css', '.js' ), array( '', '' ), $subpage));
1243 }
1248 public function isCssSubpage()
1249 {
1250 return (NS_USER == $this->mNamespace and preg_match("/\\/.*\\.css$/", $this->mTextform));
1251 }
1256 public function isJsSubpage()
1257 {
1258 return (NS_USER == $this->mNamespace and preg_match("/\\/.*\\.js$/", $this->mTextform));
1259 }
1266 public function userCanEditCssJsSubpage()
1267 {
1268 global $wgUser;
1269 return ($wgUser->isAllowed('editinterface') or preg_match('/^' . preg_quote($wgUser->getName(), '/') . '\//', $this->mTextform));
1270 }
1271
1273 {
1274 if (!$this->mRestrictionsLoaded) {
1275 $this->loadRestrictions();
1276 }
1277
1279 }
1280
1285 private function loadRestrictionsFromRow($res, $oldFashionedRestrictions = null)
1286 {
1287 $dbr = wfGetDb(DB_SLAVE);
1288
1289 $this->mRestrictions['edit'] = array();
1290 $this->mRestrictions['move'] = array();
1291
1292 # Backwards-compatibility: also load the restrictions from the page record (old format).
1293
1294 if ($oldFashionedRestrictions == null) {
1295 $oldFashionedRestrictions = $dbr->selectField('page', 'page_restrictions', array( 'page_id' => $this->getArticleID() ), __METHOD__);
1296 }
1297
1298 if ($oldFashionedRestrictions != '') {
1299 foreach (explode(':', trim($oldFashionedRestrictions)) as $restrict) {
1300 $temp = explode('=', trim($restrict));
1301 if (count($temp) == 1) {
1302 // old old format should be treated as edit/move restriction
1303 $this->mRestrictions["edit"] = explode(',', trim($temp[0]));
1304 $this->mRestrictions["move"] = explode(',', trim($temp[0]));
1305 } else {
1306 $this->mRestrictions[$temp[0]] = explode(',', trim($temp[1]));
1307 }
1308 }
1309
1310 $this->mOldRestrictions = true;
1311 $this->mCascadeRestriction = false;
1312 $this->mRestrictionsExpiry = Block::decodeExpiry('');
1313 }
1314
1315 if ($dbr->numRows($res)) {
1316 # Current system - load second to make them override.
1317 $now = wfTimestampNow();
1318 $purgeExpired = false;
1319
1320 while ($row = $dbr->fetchObject($res)) {
1321 # Cycle through all the restrictions.
1322
1323 // This code should be refactored, now that it's being used more generally,
1324 // But I don't really see any harm in leaving it in Block for now -werdna
1325 $expiry = Block::decodeExpiry($row->pr_expiry);
1326
1327 // Only apply the restrictions if they haven't expired!
1328 if (!$expiry || $expiry > $now) {
1329 $this->mRestrictionsExpiry = $expiry;
1330 $this->mRestrictions[$row->pr_type] = explode(',', trim($row->pr_level));
1331
1332 $this->mCascadeRestriction |= $row->pr_cascade;
1333 } else {
1334 // Trigger a lazy purge of expired restrictions
1335 $purgeExpired = true;
1336 }
1337 }
1338
1339 if ($purgeExpired) {
1341 }
1342 }
1343
1344 $this->mRestrictionsLoaded = true;
1345 }
1346
1347 public function loadRestrictions($oldFashionedRestrictions = null)
1348 {
1349 if (!$this->mRestrictionsLoaded) {
1350 $dbr = wfGetDB(DB_SLAVE);
1351
1352 $res = $dbr->select(
1353 'page_restrictions',
1354 '*',
1355 array( 'pr_page' => $this->getArticleID() ),
1356 __METHOD__
1357 );
1358
1359 $this->loadRestrictionsFromRow($res, $oldFashionedRestrictions);
1360 }
1361 }
1362
1366 public static function purgeExpiredRestrictions()
1367 {
1368 $dbw = wfGetDB(DB_MASTER);
1369 $dbw->delete(
1370 'page_restrictions',
1371 array( 'pr_expiry < ' . $dbw->addQuotes($dbw->timestamp()) ),
1372 __METHOD__
1373 );
1374 }
1375
1382 public function getRestrictions($action)
1383 {
1384 if ($this->exists()) {
1385 if (!$this->mRestrictionsLoaded) {
1386 $this->loadRestrictions();
1387 }
1388 return $this->mRestrictions[$action] ?? array();
1389 } else {
1390 return array();
1391 }
1392 }
1393
1398 public function isDeleted()
1399 {
1400 $fname = 'Title::isDeleted';
1401 if ($this->getNamespace() < 0) {
1402 $n = 0;
1403 } else {
1404 $dbr = wfGetDB(DB_SLAVE);
1405 $n = $dbr->selectField('archive', 'COUNT(*)', array( 'ar_namespace' => $this->getNamespace(),
1406 'ar_title' => $this->getDBkey() ), $fname);
1407 if ($this->getNamespace() == NS_IMAGE) {
1408 $n += $dbr->selectField(
1409 'filearchive',
1410 'COUNT(*)',
1411 array( 'fa_name' => $this->getDBkey() ),
1412 $fname
1413 );
1414 }
1415 }
1416 return (int) $n;
1417 }
1418
1426 public function getArticleID($flags = 0)
1427 {
1428 $linkCache = &LinkCache::singleton();
1429 if ($flags & GAID_FOR_UPDATE) {
1430 $oldUpdate = $linkCache->forUpdate(true);
1431 $this->mArticleID = $linkCache->addLinkObj($this);
1432 $linkCache->forUpdate($oldUpdate);
1433 } else {
1434 if (-1 == $this->mArticleID) {
1435 $this->mArticleID = $linkCache->addLinkObj($this);
1436 }
1437 }
1438 return $this->mArticleID;
1439 }
1440
1441 public function getLatestRevID()
1442 {
1443 if ($this->mLatestID !== false) {
1444 return $this->mLatestID;
1445 }
1446
1447 $db = wfGetDB(DB_SLAVE);
1448 return $this->mLatestID = $db->selectField(
1449 'revision',
1450 "max(rev_id)",
1451 array('rev_page' => $this->getArticleID()),
1452 'Title::getLatestRevID'
1453 );
1454 }
1455
1466 public function resetArticleID($newid)
1467 {
1468 $linkCache = &LinkCache::singleton();
1469 $linkCache->clearBadLink($this->getPrefixedDBkey());
1470
1471 if (0 == $newid) {
1472 $this->mArticleID = -1;
1473 } else {
1474 $this->mArticleID = $newid;
1475 }
1476 $this->mRestrictionsLoaded = false;
1477 $this->mRestrictions = array();
1478 }
1479
1484 public function invalidateCache()
1485 {
1486 global $wgUseFileCache;
1487
1488 if (wfReadOnly()) {
1489 return;
1490 }
1491
1492 $dbw = wfGetDB(DB_MASTER);
1493 $success = $dbw->update(
1494 'page',
1495 array( /* SET */
1496 'page_touched' => $dbw->timestamp()
1497 ),
1498 array( /* WHERE */
1499 'page_namespace' => $this->getNamespace() ,
1500 'page_title' => $this->getDBkey()
1501 ),
1502 'Title::invalidateCache'
1503 );
1504
1505 if ($wgUseFileCache) {
1506 $cache = new HTMLFileCache($this);
1507 @unlink($cache->fileCacheName());
1508 }
1509
1510 return $success;
1511 }
1512
1521 /* private */ public function prefix($name)
1522 {
1523 $p = '';
1524 if ('' != $this->mInterwiki) {
1525 $p = $this->mInterwiki . ':';
1526 }
1527 if (0 != $this->mNamespace) {
1528 $p .= $this->getNsText() . ':';
1529 }
1530 return $p . $name;
1531 }
1532
1543 private function secureAndSplit()
1544 {
1545 global $wgContLang, $wgLocalInterwiki, $wgCapitalLinks;
1546
1547 # Initialisation
1548 static $rxTc = false;
1549 if (!$rxTc) {
1550 # % is needed as well
1551 $rxTc = '/[^' . Title::legalChars() . ']|%[0-9A-Fa-f]{2}/S';
1552 }
1553
1554 $this->mInterwiki = $this->mFragment = '';
1555 $this->mNamespace = $this->mDefaultNamespace; # Usually NS_MAIN
1556
1557 $dbkey = $this->mDbkeyform;
1558
1559 # Strip Unicode bidi override characters.
1560 # Sometimes they slip into cut-n-pasted page titles, where the
1561 # override chars get included in list displays.
1562 $dbkey = str_replace("\xE2\x80\x8E", '', $dbkey); // 200E LEFT-TO-RIGHT MARK
1563 $dbkey = str_replace("\xE2\x80\x8F", '', $dbkey); // 200F RIGHT-TO-LEFT MARK
1564
1565 # Clean up whitespace
1566 #
1567 $dbkey = preg_replace('/[ _]+/', '_', $dbkey);
1568 $dbkey = trim($dbkey, '_');
1569
1570 if ('' == $dbkey) {
1571 return false;
1572 }
1573
1574 if (false !== strpos($dbkey, UTF8_REPLACEMENT)) {
1575 # Contained illegal UTF-8 sequences or forbidden Unicode chars.
1576 return false;
1577 }
1578
1579 $this->mDbkeyform = $dbkey;
1580
1581 # Initial colon indicates main namespace rather than specified default
1582 # but should not create invalid {ns,title} pairs such as {0,Project:Foo}
1583 if (':' == $dbkey[0]) {
1584 $this->mNamespace = NS_MAIN;
1585 $dbkey = substr($dbkey, 1); # remove the colon but continue processing
1586 $dbkey = trim($dbkey, '_'); # remove any subsequent whitespace
1587 }
1588
1589 # Namespace or interwiki prefix
1590 $firstPass = true;
1591 do {
1592 $m = array();
1593 if (preg_match("/^(.+?)_*:_*(.*)$/S", $dbkey, $m)) {
1594 $p = $m[1];
1595 if ($ns = $wgContLang->getNsIndex($p)) {
1596 # Ordinary namespace
1597 $dbkey = $m[2];
1598 $this->mNamespace = $ns;
1599 } elseif ($this->getInterwikiLink($p)) {
1600 if (!$firstPass) {
1601 # Can't make a local interwiki link to an interwiki link.
1602 # That's just crazy!
1603 return false;
1604 }
1605
1606 # Interwiki link
1607 $dbkey = $m[2];
1608 $this->mInterwiki = $wgContLang->lc($p);
1609
1610 # Redundant interwiki prefix to the local wiki
1611 if (0 == strcasecmp($this->mInterwiki, $wgLocalInterwiki)) {
1612 if ($dbkey == '') {
1613 # Can't have an empty self-link
1614 return false;
1615 }
1616 $this->mInterwiki = '';
1617 $firstPass = false;
1618 # Do another namespace split...
1619 continue;
1620 }
1621
1622 # If there's an initial colon after the interwiki, that also
1623 # resets the default namespace
1624 if ($dbkey !== '' && $dbkey[0] == ':') {
1625 $this->mNamespace = NS_MAIN;
1626 $dbkey = substr($dbkey, 1);
1627 }
1628 }
1629 # If there's no recognized interwiki or namespace,
1630 # then let the colon expression be part of the title.
1631 }
1632 break;
1633 } while (true);
1634
1635 # We already know that some pages won't be in the database!
1636 #
1637 if ('' != $this->mInterwiki || NS_SPECIAL == $this->mNamespace) {
1638 $this->mArticleID = 0;
1639 }
1640 $fragment = strstr($dbkey, '#');
1641 if (false !== $fragment) {
1642 $this->setFragment($fragment);
1643 $dbkey = substr($dbkey, 0, strlen($dbkey) - strlen($fragment));
1644 # remove whitespace again: prevents "Foo_bar_#"
1645 # becoming "Foo_bar_"
1646 $dbkey = preg_replace('/_*$/', '', $dbkey);
1647 }
1648
1649 # Reject illegal characters.
1650 #
1651 if (preg_match($rxTc, $dbkey)) {
1652 return false;
1653 }
1654
1660 if (strpos($dbkey, '.') !== false &&
1661 ($dbkey === '.' || $dbkey === '..' ||
1662 strpos($dbkey, './') === 0 ||
1663 strpos($dbkey, '../') === 0 ||
1664 strpos($dbkey, '/./') !== false ||
1665 strpos($dbkey, '/../') !== false)) {
1666 return false;
1667 }
1668
1672 if (strpos($dbkey, '~~~') !== false) {
1673 return false;
1674 }
1675
1683 if (($this->mNamespace != NS_SPECIAL && strlen($dbkey) > 255) ||
1684 strlen($dbkey) > 512) {
1685 return false;
1686 }
1687
1696 if ($wgCapitalLinks && $this->mInterwiki == '') {
1697 $dbkey = $wgContLang->ucfirst($dbkey);
1698 }
1699
1705 if ($dbkey == '' &&
1706 $this->mInterwiki == '' &&
1707 $this->mNamespace != NS_MAIN) {
1708 return false;
1709 }
1710
1711 // Any remaining initial :s are illegal.
1712 if ($dbkey !== '' && ':' == $dbkey[0]) {
1713 return false;
1714 }
1715
1716 # Fill fields
1717 $this->mDbkeyform = $dbkey;
1718 $this->mUrlform = ilWikiUtil::wfUrlencode($dbkey);
1719
1720 $this->mTextform = str_replace('_', ' ', $dbkey);
1721
1722 return true;
1723 }
1724
1734 public function setFragment($fragment)
1735 {
1736 $this->mFragment = str_replace('_', ' ', substr($fragment, 1));
1737 }
1738
1743 /* public function getTalkPage() {
1744 return Title::makeTitle( Namespace::getTalk( $this->getNamespace() ), $this->getDBkey() );
1745 }*/
1746
1753 /* public function getSubjectPage() {
1754 return Title::makeTitle( Namespace::getSubject( $this->getNamespace() ), $this->getDBkey() );
1755 }*/
1756
1767 public function getLinksTo($options = '', $table = 'pagelinks', $prefix = 'pl')
1768 {
1769 $linkCache = &LinkCache::singleton();
1770
1771 if ($options) {
1772 $db = wfGetDB(DB_MASTER);
1773 } else {
1774 $db = wfGetDB(DB_SLAVE);
1775 }
1776
1777 $res = $db->select(
1778 array( 'page', $table ),
1779 array( 'page_namespace', 'page_title', 'page_id' ),
1780 array(
1781 "{$prefix}_from=page_id",
1782 "{$prefix}_namespace" => $this->getNamespace(),
1783 "{$prefix}_title" => $this->getDBkey() ),
1784 'Title::getLinksTo',
1785 $options
1786 );
1787
1788 $retVal = array();
1789 if ($db->numRows($res)) {
1790 while ($row = $db->fetchObject($res)) {
1791 if ($titleObj = Title::makeTitle($row->page_namespace, $row->page_title)) {
1792 $linkCache->addGoodLinkObj($row->page_id, $titleObj);
1793 $retVal[] = $titleObj;
1794 }
1795 }
1796 }
1797 $db->freeResult($res);
1798 return $retVal;
1799 }
1800
1811 public function getTemplateLinksTo($options = '')
1812 {
1813 return $this->getLinksTo($options, 'templatelinks', 'tl');
1814 }
1815
1822 public function getBrokenLinksFrom($options = '')
1823 {
1824 if ($options) {
1825 $db = wfGetDB(DB_MASTER);
1826 } else {
1827 $db = wfGetDB(DB_SLAVE);
1828 }
1829
1830 $res = $db->safeQuery(
1831 "SELECT pl_namespace, pl_title
1832 FROM !
1833 LEFT JOIN !
1834 ON pl_namespace=page_namespace
1835 AND pl_title=page_title
1836 WHERE pl_from=?
1837 AND page_namespace IS NULL
1838 !",
1839 $db->tableName('pagelinks'),
1840 $db->tableName('page'),
1841 $this->getArticleID(),
1842 $options
1843 );
1844
1845 $retVal = array();
1846 if ($db->numRows($res)) {
1847 while ($row = $db->fetchObject($res)) {
1848 $retVal[] = Title::makeTitle($row->pl_namespace, $row->pl_title);
1849 }
1850 }
1851 $db->freeResult($res);
1852 return $retVal;
1853 }
1854
1855
1862 public function getSquidURLs()
1863 {
1864 global $wgContLang;
1865
1866 $urls = array(
1867 $this->getInternalURL(),
1868 $this->getInternalURL('action=history')
1869 );
1870
1871 // purge variant urls as well
1872 if ($wgContLang->hasVariants()) {
1873 $variants = $wgContLang->getVariants();
1874 foreach ($variants as $vCode) {
1875 if ($vCode == $wgContLang->getCode()) {
1876 continue;
1877 } // we don't want default variant
1878 $urls[] = $this->getInternalURL('', $vCode);
1879 }
1880 }
1881
1882 return $urls;
1883 }
1884
1885 public function purgeSquid()
1886 {
1887 global $wgUseSquid;
1888 if ($wgUseSquid) {
1889 $urls = $this->getSquidURLs();
1890 $u = new SquidUpdate($urls);
1891 $u->doUpdate();
1892 }
1893 }
1894
1899 public function moveNoAuth(&$nt)
1900 {
1901 return $this->moveTo($nt, false);
1902 }
1903
1913 public function isValidMoveOperation($nt, $auth = true)
1914 {
1915 if (!$this or !$nt) {
1916 return 'badtitletext';
1917 }
1918 if ($this->equals($nt)) {
1919 return 'selfmove';
1920 }
1921 if (!$this->isMovable() || !$nt->isMovable()) {
1922 return 'immobile_namespace';
1923 }
1924
1925 $oldid = $this->getArticleID();
1926 $newid = $nt->getArticleID();
1927
1928 if (strlen($nt->getDBkey()) < 1) {
1929 return 'articleexists';
1930 }
1931 if (('' == $this->getDBkey()) ||
1932 (!$oldid) ||
1933 ('' == $nt->getDBkey())) {
1934 return 'badarticleerror';
1935 }
1936
1937 if ($auth && (
1938 !$this->userCan('edit') || !$nt->userCan('edit') ||
1939 !$this->userCan('move') || !$nt->userCan('move')
1940 )) {
1941 return 'protectedpage';
1942 }
1943
1944 # The move is allowed only if (1) the target doesn't exist, or
1945 # (2) the target is a redirect to the source, and has no history
1946 # (so we can undo bad moves right after they're done).
1947
1948 if (0 != $newid) { # Target exists; check for validity
1949 if (!$this->isValidMoveTarget($nt)) {
1950 return 'articleexists';
1951 }
1952 }
1953 return true;
1954 }
1955
1963 public function moveTo(&$nt, $auth = true, $reason = '')
1964 {
1965 $err = $this->isValidMoveOperation($nt, $auth);
1966 if (is_string($err)) {
1967 return $err;
1968 }
1969
1970 $pageid = $this->getArticleID();
1971 if ($nt->exists()) {
1972 $this->moveOverExistingRedirect($nt, $reason);
1973 $pageCountChange = 0;
1974 } else { # Target didn't exist, do normal move.
1975 $this->moveToNewTitle($nt, $reason);
1976 $pageCountChange = 1;
1977 }
1978 $redirid = $this->getArticleID();
1979
1980 # Fixing category links (those without piped 'alternate' names) to be sorted under the new title
1981 $dbw = wfGetDB(DB_MASTER);
1982 $categorylinks = $dbw->tableName('categorylinks');
1983 $sql = "UPDATE $categorylinks SET cl_sortkey=" . $dbw->addQuotes($nt->getPrefixedText()) .
1984 " WHERE cl_from=" . $dbw->addQuotes($pageid) .
1985 " AND cl_sortkey=" . $dbw->addQuotes($this->getPrefixedText());
1986 $dbw->query($sql, 'SpecialMovepage::doSubmit');
1987
1988 # Update watchlists
1989
1990 $oldnamespace = $this->getNamespace() & ~1;
1991 $newnamespace = $nt->getNamespace() & ~1;
1992 $oldtitle = $this->getDBkey();
1993 $newtitle = $nt->getDBkey();
1994
1995 if ($oldnamespace != $newnamespace || $oldtitle != $newtitle) {
1996 WatchedItem::duplicateEntries($this, $nt);
1997 }
1998
1999 # Update search engine
2000 $u = new SearchUpdate($pageid, $nt->getPrefixedDBkey());
2001 $u->doUpdate();
2002 $u = new SearchUpdate($redirid, $this->getPrefixedDBkey(), '');
2003 $u->doUpdate();
2004
2005 # Update site_stats
2006 if ($this->isContentPage() && !$nt->isContentPage()) {
2007 # No longer a content page
2008 # Not viewed, edited, removing
2009 $u = new SiteStatsUpdate(0, 1, -1, $pageCountChange);
2010 } elseif (!$this->isContentPage() && $nt->isContentPage()) {
2011 # Now a content page
2012 # Not viewed, edited, adding
2013 $u = new SiteStatsUpdate(0, 1, +1, $pageCountChange);
2014 } elseif ($pageCountChange) {
2015 # Redirect added
2016 $u = new SiteStatsUpdate(0, 0, 0, 1);
2017 } else {
2018 # Nothing special
2019 $u = false;
2020 }
2021 if ($u) {
2022 $u->doUpdate();
2023 }
2024
2025 global $wgUser;
2026 wfRunHooks('TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid ));
2027 return true;
2028 }
2029
2037 private function moveOverExistingRedirect($nt, $reason = '')
2038 {
2039 global $wgUseSquid;
2041 $comment = wfMsgForContent('1movedto2_redir', $this->getPrefixedText(), $nt->getPrefixedText());
2042
2043 if ($reason) {
2044 $comment .= ": $reason";
2045 }
2046
2047 $now = wfTimestampNow();
2048 $newid = $nt->getArticleID();
2049 $oldid = $this->getArticleID();
2050 $dbw = wfGetDB(DB_MASTER);
2051 $linkCache = &LinkCache::singleton();
2052
2053 # Delete the old redirect. We don't save it to history since
2054 # by definition if we've got here it's rather uninteresting.
2055 # We have to remove it so that the next step doesn't trigger
2056 # a conflict on the unique namespace+title index...
2057 $dbw->delete('page', array( 'page_id' => $newid ), $fname);
2058
2059 # Save a null revision in the page's history notifying of the move
2060 $nullRevision = Revision::newNullRevision($dbw, $oldid, $comment, true);
2061 $nullRevId = $nullRevision->insertOn($dbw);
2062
2063 # Change the name of the target page:
2064 $dbw->update(
2065 'page',
2066 /* SET */
2067 array(
2068 'page_touched' => $dbw->timestamp($now),
2069 'page_namespace' => $nt->getNamespace(),
2070 'page_title' => $nt->getDBkey(),
2071 'page_latest' => $nullRevId,
2072 ),
2073 /* WHERE */
2074 array( 'page_id' => $oldid ),
2075 $fname
2076 );
2077 $linkCache->clearLink($nt->getPrefixedDBkey());
2078
2079 # Recreate the redirect, this time in the other direction.
2080 $mwRedir = MagicWord::get('redirect');
2081 $redirectText = $mwRedir->getSynonym(0) . ' [[' . $nt->getPrefixedText() . "]]\n";
2082 $redirectArticle = new Article($this);
2083 $newid = $redirectArticle->insertOn($dbw);
2084 $redirectRevision = new Revision(array(
2085 'page' => $newid,
2086 'comment' => $comment,
2087 'text' => $redirectText ));
2088 $redirectRevision->insertOn($dbw);
2089 $redirectArticle->updateRevisionOn($dbw, $redirectRevision, 0);
2090 $linkCache->clearLink($this->getPrefixedDBkey());
2091
2092 # Log the move
2093 $log = new LogPage('move');
2094 $log->addEntry('move_redir', $this, $reason, array( 1 => $nt->getPrefixedText() ));
2095
2096 # Now, we record the link from the redirect to the new title.
2097 # It should have no other outgoing links...
2098 $dbw->delete('pagelinks', array( 'pl_from' => $newid ), $fname);
2099 $dbw->insert(
2100 'pagelinks',
2101 array(
2102 'pl_from' => $newid,
2103 'pl_namespace' => $nt->getNamespace(),
2104 'pl_title' => $nt->getDBkey() ),
2105 $fname
2106 );
2107
2108 # Purge squid
2109 if ($wgUseSquid) {
2110 $urls = array_merge($nt->getSquidURLs(), $this->getSquidURLs());
2111 $u = new SquidUpdate($urls);
2112 $u->doUpdate();
2113 }
2114 }
2115
2120 private function moveToNewTitle(&$nt, $reason = '')
2121 {
2122 global $wgUseSquid;
2123 $fname = 'MovePageForm::moveToNewTitle';
2124 $comment = wfMsgForContent('1movedto2', $this->getPrefixedText(), $nt->getPrefixedText());
2125 if ($reason) {
2126 $comment .= ": $reason";
2127 }
2128
2129 $newid = $nt->getArticleID();
2130 $oldid = $this->getArticleID();
2131 $dbw = wfGetDB(DB_MASTER);
2132 $now = $dbw->timestamp();
2133 $linkCache = &LinkCache::singleton();
2134
2135 # Save a null revision in the page's history notifying of the move
2136 $nullRevision = Revision::newNullRevision($dbw, $oldid, $comment, true);
2137 $nullRevId = $nullRevision->insertOn($dbw);
2138
2139 # Rename cur entry
2140 $dbw->update(
2141 'page',
2142 /* SET */
2143 array(
2144 'page_touched' => $now,
2145 'page_namespace' => $nt->getNamespace(),
2146 'page_title' => $nt->getDBkey(),
2147 'page_latest' => $nullRevId,
2148 ),
2149 /* WHERE */
2150 array( 'page_id' => $oldid ),
2151 $fname
2152 );
2153
2154 $linkCache->clearLink($nt->getPrefixedDBkey());
2155
2156 # Insert redirect
2157 $mwRedir = MagicWord::get('redirect');
2158 $redirectText = $mwRedir->getSynonym(0) . ' [[' . $nt->getPrefixedText() . "]]\n";
2159 $redirectArticle = new Article($this);
2160 $newid = $redirectArticle->insertOn($dbw);
2161 $redirectRevision = new Revision(array(
2162 'page' => $newid,
2163 'comment' => $comment,
2164 'text' => $redirectText ));
2165 $redirectRevision->insertOn($dbw);
2166 $redirectArticle->updateRevisionOn($dbw, $redirectRevision, 0);
2167 $linkCache->clearLink($this->getPrefixedDBkey());
2168
2169 # Log the move
2170 $log = new LogPage('move');
2171 $log->addEntry('move', $this, $reason, array( 1 => $nt->getPrefixedText()));
2172
2173 # Purge caches as per article creation
2174 Article::onArticleCreate($nt);
2175
2176 # Record the just-created redirect's linking to the page
2177 $dbw->insert(
2178 'pagelinks',
2179 array(
2180 'pl_from' => $newid,
2181 'pl_namespace' => $nt->getNamespace(),
2182 'pl_title' => $nt->getDBkey() ),
2183 $fname
2184 );
2185
2186 # Purge old title from squid
2187 # The new title, and links to the new title, are purged in Article::onArticleCreate()
2188 $this->purgeSquid();
2189 }
2190
2197 public function isValidMoveTarget($nt)
2198 {
2199 $fname = 'Title::isValidMoveTarget';
2200 $dbw = wfGetDB(DB_MASTER);
2201
2202 # Is it a redirect?
2203 $id = $nt->getArticleID();
2204 $obj = $dbw->selectRow(
2205 array( 'page', 'revision', 'text'),
2206 array( 'page_is_redirect','old_text','old_flags' ),
2207 array( 'page_id' => $id, 'page_latest=rev_id', 'rev_text_id=old_id' ),
2208 $fname,
2209 'FOR UPDATE'
2210 );
2211
2212 if (!$obj || 0 == $obj->page_is_redirect) {
2213 # Not a redirect
2214 wfDebug(__METHOD__ . ": not a redirect\n");
2215 return false;
2216 }
2217 $text = Revision::getRevisionText($obj);
2218
2219 # Does the redirect point to the source?
2220 # Or is it a broken self-redirect, usually caused by namespace collisions?
2221 $m = array();
2222 if (preg_match("/\\[\\[\\s*([^\\]\\|]*)]]/", $text, $m)) {
2223 $redirTitle = Title::newFromText($m[1]);
2224 if (!is_object($redirTitle) ||
2225 ($redirTitle->getPrefixedDBkey() != $this->getPrefixedDBkey() &&
2226 $redirTitle->getPrefixedDBkey() != $nt->getPrefixedDBkey())) {
2227 wfDebug(__METHOD__ . ": redirect points to other page\n");
2228 return false;
2229 }
2230 } else {
2231 # Fail safe
2232 wfDebug(__METHOD__ . ": failsafe\n");
2233 return false;
2234 }
2235
2236 # Does the article have a history?
2237 $row = $dbw->selectRow(
2238 array( 'page', 'revision'),
2239 array( 'rev_id' ),
2240 array( 'page_namespace' => $nt->getNamespace(),
2241 'page_title' => $nt->getDBkey(),
2242 'page_id=rev_page AND page_latest != rev_id'
2243 ),
2244 $fname,
2245 'FOR UPDATE'
2246 );
2247
2248 # Return true if there was no history
2249 return $row === false;
2250 }
2251
2259 public function getParentCategories()
2260 {
2261 global $wgContLang;
2262 $data = [];
2263 $titlekey = $this->getArticleID();
2264 $dbr = wfGetDB(DB_SLAVE);
2265 $categorylinks = $dbr->tableName('categorylinks');
2266
2267 # NEW SQL
2268 $sql = "SELECT * FROM $categorylinks"
2269 . " WHERE cl_from='$titlekey'"
2270 . " AND cl_from <> '0'"
2271 . " ORDER BY cl_sortkey";
2272
2273 $res = $dbr->query($sql) ;
2274
2275 if ($dbr->numRows($res) > 0) {
2276 while ($x = $dbr->fetchObject($res)) {
2277 //$data[] = Title::newFromText($wgContLang->getNSText ( NS_CATEGORY ).':'.$x->cl_to);
2278 $data[$wgContLang->getNSText(NS_CATEGORY) . ':' . $x->cl_to] = $this->getFullText();
2279 }
2280 $dbr->freeResult($res) ;
2281 } else {
2282 $data = '';
2283 }
2284 return $data;
2285 }
2286
2292 public function getParentCategoryTree($children = array())
2293 {
2294 $parents = $this->getParentCategories();
2295 $stack = [];
2296 if ($parents != '') {
2297 foreach ($parents as $parent => $current) {
2298 if (array_key_exists($parent, $children)) {
2299 # Circular reference
2300 $stack[$parent] = array();
2301 } else {
2302 $nt = Title::newFromText($parent);
2303 if ($nt) {
2304 $stack[$parent] = $nt->getParentCategoryTree($children + array($parent => 1));
2305 }
2306 }
2307 }
2308 return $stack;
2309 } else {
2310 return array();
2311 }
2312 }
2313
2314
2321 public function pageCond()
2322 {
2323 return array( 'page_namespace' => $this->mNamespace, 'page_title' => $this->mDbkeyform );
2324 }
2325
2331 public function getPreviousRevisionID($revision)
2332 {
2333 $dbr = wfGetDB(DB_SLAVE);
2334 return $dbr->selectField(
2335 'revision',
2336 'rev_id',
2337 'rev_page=' . $this->getArticleID() .
2338 ' AND rev_id<' . intval($revision) . ' ORDER BY rev_id DESC'
2339 );
2340 }
2341
2347 public function getNextRevisionID($revision)
2348 {
2349 $dbr = wfGetDB(DB_SLAVE);
2350 return $dbr->selectField(
2351 'revision',
2352 'rev_id',
2353 'rev_page=' . $this->getArticleID() .
2354 ' AND rev_id>' . intval($revision) . ' ORDER BY rev_id'
2355 );
2356 }
2357
2364 public function countRevisionsBetween($old, $new)
2365 {
2366 $dbr = wfGetDB(DB_SLAVE);
2367 return $dbr->selectField(
2368 'revision',
2369 'count(*)',
2370 'rev_page = ' . $this->getArticleID() .
2371 ' AND rev_id > ' . intval($old) .
2372 ' AND rev_id < ' . intval($new)
2373 );
2374 }
2375
2382 public function equals($title)
2383 {
2384 // Note: === is necessary for proper matching of number-like titles.
2385 return $this->getInterwiki() === $title->getInterwiki()
2386 && $this->getNamespace() == $title->getNamespace()
2387 && $this->getDBkey() === $title->getDBkey();
2388 }
2389
2394 public function exists()
2395 {
2396 return $this->getArticleID() != 0;
2397 }
2398
2405 public function isAlwaysKnown()
2406 {
2407 return $this->isExternal() || (0 == $this->mNamespace && "" == $this->mDbkeyform)
2408 || NS_SPECIAL == $this->mNamespace;
2409 }
2410
2416 public function touchLinks()
2417 {
2418 $u = new HTMLCacheUpdate($this, 'pagelinks');
2419 $u->doUpdate();
2420
2421 if ($this->getNamespace() == NS_CATEGORY) {
2422 $u = new HTMLCacheUpdate($this, 'categorylinks');
2423 $u->doUpdate();
2424 }
2425 }
2426
2430 public function getTouched()
2431 {
2432 $dbr = wfGetDB(DB_SLAVE);
2433 $touched = $dbr->selectField(
2434 'page',
2435 'page_touched',
2436 array(
2437 'page_namespace' => $this->getNamespace(),
2438 'page_title' => $this->getDBkey()
2439 ),
2440 __METHOD__
2441 );
2442 return $touched;
2443 }
2444
2445 public function trackbackURL()
2446 {
2447 global $wgTitle, $wgScriptPath, $wgServer;
2448
2449 return "$wgServer$wgScriptPath/trackback.php?article="
2450 . htmlspecialchars(urlencode($wgTitle->getPrefixedDBkey()));
2451 }
2452
2453 public function trackbackRDF()
2454 {
2455 $url = htmlspecialchars($this->getFullURL());
2456 $title = htmlspecialchars($this->getText());
2457 $tburl = $this->trackbackURL();
2458
2459 return "
2460<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
2461 xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
2462 xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\">
2463<rdf:Description
2464 rdf:about=\"$url\"
2465 dc:identifier=\"$url\"
2466 dc:title=\"$title\"
2467 trackback:ping=\"$tburl\" />
2468</rdf:RDF>";
2469 }
2470
2475 public function getNamespaceKey()
2476 {
2477 global $wgContLang;
2478 switch ($this->getNamespace()) {
2479 case NS_MAIN:
2480 case NS_TALK:
2481 return 'nstab-main';
2482 case NS_USER:
2483 case NS_USER_TALK:
2484 return 'nstab-user';
2485 case NS_MEDIA:
2486 return 'nstab-media';
2487 case NS_SPECIAL:
2488 return 'nstab-special';
2489 case NS_PROJECT:
2490 case NS_PROJECT_TALK:
2491 return 'nstab-project';
2492 case NS_IMAGE:
2493 case NS_IMAGE_TALK:
2494 return 'nstab-image';
2495 case NS_MEDIAWIKI:
2496 case NS_MEDIAWIKI_TALK:
2497 return 'nstab-mediawiki';
2498 case NS_TEMPLATE:
2499 case NS_TEMPLATE_TALK:
2500 return 'nstab-template';
2501 case NS_HELP:
2502 case NS_HELP_TALK:
2503 return 'nstab-help';
2504 case NS_CATEGORY:
2505 case NS_CATEGORY_TALK:
2506 return 'nstab-category';
2507 default:
2508 return 'nstab-' . $wgContLang->lc($this->getSubjectNsText());
2509 }
2510 }
2511
2516 public function isSpecial($name)
2517 {
2518 if ($this->getNamespace() == NS_SPECIAL) {
2519 list($thisName, /* $subpage */ ) = SpecialPage::resolveAliasWithSubpage($this->getDBkey());
2520 if ($name == $thisName) {
2521 return true;
2522 }
2523 }
2524 return false;
2525 }
2526
2531 public function fixSpecialName()
2532 {
2533 if ($this->getNamespace() == NS_SPECIAL) {
2534 $canonicalName = SpecialPage::resolveAlias($this->mDbkeyform);
2535 if ($canonicalName) {
2536 $localName = SpecialPage::getLocalNameFor($canonicalName);
2537 if ($localName != $this->mDbkeyform) {
2538 return Title::makeTitle(NS_SPECIAL, $localName);
2539 }
2540 }
2541 }
2542 return $this;
2543 }
2544
2552/* public function isContentPage() {
2553 return Namespace::isContent( $this->getNamespace() );
2554 }*/
2555}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
const NS_MAIN
Definition: Title.php:5
const MW_TITLECACHE_MAX
Definition: Title.php:15
const GAID_FOR_UPDATE
Definition: Title.php:8
const NS_SPECIAL
Definition: Title.php:6
static return function(ContainerConfigurator $containerConfigurator)
Definition: basic_rector.php:9
$comment
Definition: buildRTE.php:72
static decodeCharReferences($text)
Decode any character references, numeric or named entities, in the text and return a UTF-8 string.
Definition: Sanitizer.php:1041
Title class.
Definition: Title.php:27
getInternalURL($query='', $variant=false)
Get the URL form for an internal link.
Definition: Title.php:885
escapeFullURL($query='')
Get an HTML-escaped version of the URL form, suitable for using in a link, including the server name ...
Definition: Title.php:871
getTouched()
Get the last touched timestamp.
Definition: Title.php:2430
getNamespace()
Get the namespace index, i.e.
Definition: Title.php:528
static getInterwikiCached($key)
Fetch interwiki prefix data from local cache in constant database.
Definition: Title.php:406
userCanRead()
Would anybody with sufficient privileges be able to move this page? Some pages just aren't movable.
Definition: Title.php:1173
static $titleCache
Static cache variables.
Definition: Title.php:31
invalidateCache()
Updates page_touched for this page; called from LinksUpdate.php.
Definition: Title.php:1484
purgeSquid()
Definition: Title.php:1885
$mHasCascadingRestrictions
Definition: Title.php:55
moveTo(&$nt, $auth=true, $reason='')
Move a title to a new location.
Definition: Title.php:1963
$mInterwiki
Definition: Title.php:48
$mTextform
All member variables should be considered private Please use the accessor functions.
Definition: Title.php:44
nameOf($id)
Get the prefixed DB key associated with an ID.
Definition: Title.php:298
getNextRevisionID($revision)
Get the revision ID of the next revision.
Definition: Title.php:2347
secureAndSplit()
Secure and split - main initialisation function for this object.
Definition: Title.php:1543
getSkinFromCssJsSubpage()
Trim down a .css or .js subpage title to get the corresponding skin name.
Definition: Title.php:1238
getDefaultNamespace()
Get the default namespace index, for when there is no namespace.
Definition: Title.php:611
$mArticleID
Definition: Title.php:50
resetArticleID($newid)
This clears some fields in this object, and clears any associated keys in the "bad links" section of ...
Definition: Title.php:1466
$mNamespace
Definition: Title.php:47
getFragment()
Get the Title fragment (i.e.
Definition: Title.php:591
isProtected($action='')
Does the title correspond to a protected article?
Definition: Title.php:960
getIndexTitle()
Get title for search index.
Definition: Title.php:621
getPrefixedURL()
Get a URL-encoded title (not an actual URL) including interwiki.
Definition: Title.php:718
getLinksTo($options='', $table='pagelinks', $prefix='pl')
Get a Title object associated with the talk page of this article.
Definition: Title.php:1767
$mWatched
Definition: Title.php:61
prefix($name)
Prefix some arbitrary text with the namespace or interwiki prefix of this object.
Definition: Title.php:1521
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:114
areRestrictionsCascading()
Definition: Title.php:1272
$mDbkeyform
Definition: Title.php:46
$mRestrictionsLoaded
Definition: Title.php:57
getEscapedText()
Get the HTML-escaped displayable text form.
Definition: Title.php:913
getFullText()
Get the prefixed title with spaces, plus any fragment (part beginning with '#')
Definition: Title.php:659
getFullURL($query='', $variant=false)
Get a real URL referring to this title, with interwiki link and fragment.
Definition: Title.php:741
isLocal()
Determine whether the object refers to a page within this project.
Definition: Title.php:452
moveNoAuth(&$nt)
Move this page without authentication.
Definition: Title.php:1899
$mCascadeRestrictionSources
Definition: Title.php:56
static makeTitleSafe($ns, $title)
Create a new Title from a namespace index and a DB key.
Definition: Title.php:265
quickUserCan($action)
Can $wgUser perform $action on this page? This skips potentially expensive cascading permission check...
Definition: Title.php:1018
fixSpecialName()
If the Title refers to a special page alias which is not the local default, returns a new Title which...
Definition: Title.php:2531
static legalChars()
Get a regex character class describing the legal characters in a link.
Definition: Title.php:316
getPrefixedDBkey()
Get the prefixed database key form.
Definition: Title.php:631
getNsText()
Get the namespace text.
Definition: Title.php:536
static purgeExpiredRestrictions()
Purge expired restrictions from the page_restrictions table.
Definition: Title.php:1366
equals($title)
Compare with another title.
Definition: Title.php:2382
userCanCreate($doExpensiveQueries=true)
Can $wgUser create this page?
Definition: Title.php:1142
static $interwikiCache
Definition: Title.php:32
isTrans()
Determine whether the object refers to a page within this project and is transcludable.
Definition: Title.php:470
static makeName($ns, $title)
Definition: Title.php:332
touchLinks()
Update page_touched timestamps and send squid purge messages for pages linking to this title.
Definition: Title.php:2416
trackbackRDF()
Definition: Title.php:2453
userIsWatching()
Is $wgUser is watching this page?
Definition: Title.php:995
isExternal()
Is this Title interwiki?
Definition: Title.php:922
getFragmentForURL()
Get the fragment in URL form, including the "#" character if there is one.
Definition: Title.php:599
static newFromID($id)
Create a new Title from an article ID.
Definition: Title.php:194
$mRestrictionsExpiry
Definition: Title.php:54
getArticleID($flags=0)
Get the article ID for this Title from the link cache, adding it if necessary.
Definition: Title.php:1426
static & makeTitle($ns, $title)
Create a new Title from a namespace index and a DB key.
Definition: Title.php:243
getSubpageUrlForm()
Get a URL-encoded form of the subpage text.
Definition: Title.php:706
getDBkey()
Get the main part with underscores.
Definition: Title.php:520
countRevisionsBetween($old, $new)
Get the number of revisions between the given revision IDs.
Definition: Title.php:2364
userCanEditCssJsSubpage()
Protect css/js subpages of user pages: can $wgUser edit this page?
Definition: Title.php:1266
userCanEdit($doExpensiveQueries=true)
Can $wgUser edit this page?
Definition: Title.php:1132
getBrokenLinksFrom($options='')
Get an array of Title objects referring to non-existent articles linked from this page.
Definition: Title.php:1822
$mRestrictions
Definition: Title.php:52
getPartialURL()
Get the URL-encoded form of the main part.
Definition: Title.php:512
getBaseText()
Get the base name, i.e.
Definition: Title.php:672
getText()
Simple accessors.
Definition: Title.php:504
pageCond()
Get an associative array for selecting this title from the "page" table.
Definition: Title.php:2321
isSemiProtected($action='edit')
Is this page "semi-protected" - the only protection is autoconfirm?
Definition: Title.php:933
isJsSubpage()
Is this a .js subpage of a user page?
Definition: Title.php:1256
userCanMove($doExpensiveQueries=true)
Can $wgUser move this page?
Definition: Title.php:1152
isSpecial($name)
Returns true if this title resolves to the named special page.
Definition: Title.php:2516
$mUrlform
Definition: Title.php:45
__construct()
#-
Definition: Title.php:69
$mLatestID
Definition: Title.php:51
static newMainPage()
Create a new Title for the Main Page.
Definition: Title.php:280
moveOverExistingRedirect($nt, $reason='')
Move page to a title which is at present a redirect to the source page.
Definition: Title.php:2037
isCssSubpage()
Is this a .css subpage of a user page?
Definition: Title.php:1248
exists()
Check if page exists.
Definition: Title.php:2394
getSquidURLs()
Get a list of URLs to purge from the Squid cache when this page changes.
Definition: Title.php:1862
getLocalURL($query='', $variant=false)
Get a URL with no fragment or server name.
Definition: Title.php:781
static newFromURL($url)
Create a new Title from URL-encoded text.
Definition: Title.php:165
isDeleted()
Is there a version of this page in the deletion archive?
Definition: Title.php:1398
static newFromDBkey($key)
Create a new Title from a prefixed DB key.
Definition: Title.php:92
setFragment($fragment)
Set the fragment for this title This is kind of bad, since except for this rarely-used function,...
Definition: Title.php:1734
loadRestrictions($oldFashionedRestrictions=null)
Definition: Title.php:1347
$mFragment
Definition: Title.php:49
getParentCategoryTree($children=array())
Get a tree of parent categories.
Definition: Title.php:2292
getEditURL()
Get the edit URL for this Title.
Definition: Title.php:898
getParentCategories()
Get categories to which this Title belongs and return an array of categories' names.
Definition: Title.php:2259
getNamespaceKey()
Generate strings used for xml 'id' names in monobook tabs.
Definition: Title.php:2475
trackbackURL()
Definition: Title.php:2445
$mCascadeRestriction
Definition: Title.php:53
static newFromIDs($ids)
Make an array of titles from an array of IDs.
Definition: Title.php:215
getInterwikiLink($key)
Returns the URL associated with an interwiki prefix.
Definition: Title.php:347
isSubpage()
Is this a talk page of some sort?
Definition: Title.php:1224
moveToNewTitle(&$nt, $reason='')
Move page to non-existing title.
Definition: Title.php:2120
$mPrefixedText
Definition: Title.php:58
getInterwiki()
Get the namespace text of the subject (rather than talk) page.
Definition: Title.php:583
isValidMoveOperation($nt, $auth=true)
Check whether a given move operation would be valid.
Definition: Title.php:1913
$mDefaultNamespace
Definition: Title.php:59
isValidMoveTarget($nt)
Checks if $this can be moved to a given Title.
Definition: Title.php:2197
userCan($action, $doExpensiveQueries=true)
Can $wgUser perform $action on this page?
Definition: Title.php:1029
getTemplateLinksTo($options='')
Get an array of Title objects using this Title as a template Also stores the IDs in the link cache.
Definition: Title.php:1811
getSubpageText()
Get the lowest-level subpage name, i.e.
Definition: Title.php:691
getPreviousRevisionID($revision)
Get the revision ID of the previous revision.
Definition: Title.php:2331
getPrefixedText()
Get the prefixed title with spaces.
Definition: Title.php:643
getRestrictions($action)
Accessor/initialisation for mRestrictions.
Definition: Title.php:1382
loadRestrictionsFromRow($res, $oldFashionedRestrictions=null)
Loads a string into mRestrictions array.
Definition: Title.php:1285
isAlwaysKnown()
Should a link should be displayed as a known link, just based on its title?
Definition: Title.php:2405
getLatestRevID()
Definition: Title.php:1441
static escapeFragmentForURL($fragment)
Escape a text fragment, say from a link, for a URL.
Definition: Title.php:484
escapeLocalURL($query='')
Get an HTML-escaped version of the URL form, suitable for using in a link, without a server name or f...
Definition: Title.php:859
static wfUrlencode(string $s)
if($err=$client->getError()) $namespace
$res
Definition: ltiservices.php:69
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
Definition: ltitoken.php:64
if($format !==null) $name
Definition: metadata.php:247
$auth
Definition: metadata.php:76
string $reason
Error message for last request processed.
Definition: System.php:102
string $key
Consumer key/client ID value.
Definition: System.php:193
form( $class_path, string $cmd)
get(string $key, Refinery\Transformation $t)
Get passed parameter, if not data passed, get key from http request.
$query
$url
$log
Definition: result.php:33