Revised styling of sister-search sidebar.
[lhc/web/wiklou.git] / includes / Title.php
index 1046a5c..e460cda 100644 (file)
@@ -22,6 +22,7 @@
  * @file
  */
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\Interwiki\InterwikiLookup;
@@ -1683,6 +1684,33 @@ class Title implements LinkTarget {
                return $url;
        }
 
+       /**
+        * Get a url appropriate for making redirects based on an untrusted url arg
+        *
+        * This is basically the same as getFullUrl(), but in the case of external
+        * interwikis, we send the user to a landing page, to prevent possible
+        * phishing attacks and the like.
+        *
+        * @note Uses current protocol by default, since technically relative urls
+        *   aren't allowed in redirects per HTTP spec, so this is not suitable for
+        *   places where the url gets cached, as might pollute between
+        *   https and non-https users.
+        * @see self::getLocalURL for the arguments.
+        * @param array|string $query
+        * @param string $proto Protocol type to use in URL
+        * @return String. A url suitable to use in an HTTP location header.
+        */
+       public function getFullUrlForRedirect( $query = '', $proto = PROTO_CURRENT ) {
+               $target = $this;
+               if ( $this->isExternal() ) {
+                       $target = SpecialPage::getTitleFor(
+                               'GoToInterwiki',
+                               $this->getPrefixedDBKey()
+                       );
+               }
+               return $target->getFullUrl( $query, false, $proto );
+       }
+
        /**
         * Get a URL with no fragment or server name (relative URL) from a Title object.
         * If this page is generated with action=render, however,
@@ -2095,7 +2123,7 @@ class Title implements LinkTarget {
        private function checkSpecialsAndNSPermissions( $action, $user, $errors, $rigor, $short ) {
                # Only 'createaccount' can be performed on special pages,
                # which don't actually exist in the DB.
-               if ( NS_SPECIAL == $this->mNamespace && $action !== 'createaccount' ) {
+               if ( $this->isSpecialPage() && $action !== 'createaccount' ) {
                        $errors[] = [ 'ns-specialprotected' ];
                }
 
@@ -2124,8 +2152,7 @@ class Title implements LinkTarget {
        private function checkCSSandJSPermissions( $action, $user, $errors, $rigor, $short ) {
                # Protect css/js subpages of user pages
                # XXX: this might be better using restrictions
-               # XXX: right 'editusercssjs' is deprecated, for backward compatibility only
-               if ( $action != 'patrol' && !$user->isAllowed( 'editusercssjs' ) ) {
+               if ( $action != 'patrol' ) {
                        if ( preg_match( '/^' . preg_quote( $user->getName(), '/' ) . '\//', $this->mTextform ) ) {
                                if ( $this->isCssSubpage() && !$user->isAllowedAny( 'editmyusercss', 'editusercss' ) ) {
                                        $errors[] = [ 'mycustomcssprotected', $action ];
@@ -2289,6 +2316,17 @@ class Title implements LinkTarget {
                        ) {
                                $errors[] = [ 'delete-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ];
                        }
+               } elseif ( $action === 'undelete' ) {
+                       if ( count( $this->getUserPermissionsErrorsInternal( 'edit', $user, $rigor, true ) ) ) {
+                               // Undeleting implies editing
+                               $errors[] = [ 'undelete-cantedit' ];
+                       }
+                       if ( !$this->exists()
+                               && count( $this->getUserPermissionsErrorsInternal( 'create', $user, $rigor, true ) )
+                       ) {
+                               // Undeleting where nothing currently exists implies creating
+                               $errors[] = [ 'undelete-cantcreate' ];
+                       }
                }
                return $errors;
        }
@@ -3388,7 +3426,7 @@ class Title implements LinkTarget {
                $this->mTextform = strtr( $this->mDbkeyform, '_', ' ' );
 
                # We already know that some pages won't be in the database!
-               if ( $this->isExternal() || $this->mNamespace == NS_SPECIAL ) {
+               if ( $this->isExternal() || $this->isSpecialPage() ) {
                        $this->mArticleID = 0;
                }
 
@@ -4030,7 +4068,10 @@ class Title implements LinkTarget {
                        $row = $db->selectRow( 'revision', Revision::selectFields(),
                                [ 'rev_page' => $pageId ],
                                __METHOD__,
-                               [ 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 ]
+                               [
+                                       'ORDER BY' => 'rev_timestamp ASC',
+                                       'IGNORE INDEX' => 'rev_timestamp'
+                               ]
                        );
                        if ( $row ) {
                                return new Revision( $row );
@@ -4610,7 +4651,7 @@ class Title implements LinkTarget {
        }
 
        /**
-        * Whether the magic words __INDEX__ and __NOINDEX__ function for  this page.
+        * Whether the magic words __INDEX__ and __NOINDEX__ function for this page.
         *
         * @return bool
         */