Without this patch, Title::getPrefixedText() would return ":Foo"
if the namespace was unknown, potentially creating a misleading
link to the main namespace. With this change, getPrefixedText()
will return something like "Special:Badtitle/NS12345:Foo".
Note that round trip behavior is broken either way.
Bug: T165149
Change-Id: I0d491a2b58ff45f207f83ee62ca6e7e6ffbf790a
Revision IDs are usually increasing as timestamp increases, but not
always. Callers almost certainly want next/previous timestamp when the
two differ.
This also takes care of a minor bug in the nearby getFirstRevision()
where it'll choose an arbitrary tied revision ID if there were multiple
revisions made in the same second.
Bug: T4930
Bug: T163532
Bug: T159319
Change-Id: Iab2060a0ad5e45edbaa0ff36e863cb014b8e876f
If the page exists, it only checks edit rights, otherwise it
checks both edit and create rights.
This would only matter on wikis that have a non-default rights
configuration where there are users with undelete rights but a
restriction level enabled that prevents them from creating/editing
pages (or they otherwise aren't allowed to edit/create)
It should be noted that the error messages aren't used in the
normal UI currently, but they could be in the future, and
extensions could potentially be using them (The backend functions
return them, but the UI functions in Special:Undelete ignore
them)
Bug: T108138
Change-Id: I164b80534cf89e0afca264e9de07431484af8508
Directly redirecting based on a url paramter might potentially
be used in a phishing attack to confuse users.
Bug: T109140
Bug: T122209
Change-Id: I6c604439320fa876719933cc7f3a3ff04fb1a6ad
They were both doing the same thing, except that getOldestRevision()
checks the master if the revision is missing on the replica.
Change-Id: I21a118c6cd5c98fb846a0a2765574c0dbdbf7220
We want the page_timestamp index to be used in this case, but sometimes
the rev_timestamp is chosen which leads to bad performance.
Also update WikiPage::getOldestRevision() which uses the exact same query.
I'll implement one in terms of the other in a follow-up commit.
Bug: T159319
Change-Id: I7c5c0a9b1af99ce2b5f4bdcc99710d8400ca8bcf
Both Title::getPreviousRevisionID and Title::getNextRevisionID
have bad performance under certain versions of MySQL/MariaDB
when the page has many revisions (in the order of dozens of
thousands). This is good enough in most cases.
However, on a contributions slave, where it has an explicity
defined extended secondary key with the primary key, the
performance is really, really bad, performing a full table scan.
By ignoring the PRIMARY KEY index, contributions slaves go from the
worst case to the best case, while not affecting the plan of regular
slaves. It is believed that more recent versions of MySQL chose the
right indexes automatically, because they can use the extended primary
key automatically, without adding it explicitly. If that doesn't
happen, we can consider adding it explicitly to the regular slaves,
too.
In any case, not using the PRIMARY gives always a much better or at
least the same performance (this never causes a regression, unlike
FORCE'ing a specific index).
Bug: T159319
Change-Id: Ibb6e5240b87bd8e2d680fc4d58fcb3db1a4721cc
Title::loadRestrictions() returns restriction levels, not the
corresponding user rights. These are mostly identical except for the
backwards-compatibility levels "sysop" and "autoconfirmed".
For create protection it calls Title::getTitleProtection() to fetch
them, but Ic5026384 changed that to return rights. Split that function
into two, an internal method that returns restriction levels for
loadRestrictions() to call and the public method that converts levels
into rights.
Bug: T85108
Change-Id: I3ea4cb9c5e37b746402744dd7a883763ee07195a
I was bored. What? Don't look at me that way.
I mostly targetted mixed tabs and spaces, but others were not spared.
Note that some of the whitespace changes are inside HTML output,
extended regexps or SQL snippets.
Change-Id: Ie206cc946459f6befcfc2d520e35ad3ea3c0f1e0
It's unreasonable to expect newbies to know that "bug 12345" means "Task T14345"
except where it doesn't, so let's just standardise on the real numbers.
Change-Id: I6f59febaf8fc96e80f8cfc11f4356283f461142a
This patch adds an ug_expiry column to the user_groups table, a timestamp
giving a date when the user group expires. A new UserGroupMembership class,
based on the Block class, manages entries in this table.
When the expiry date passes, the row in user_groups is ignored, and will
eventually be purged from the DB when UserGroupMembership::insert is next
called. Old, expired user group memberships are not kept; instead, the log
entries are available to find the history of these memberships, similar
to the way it has always worked for blocks and protections.
Anyone getting user group info through the User object will get correct
information. However, code that reads the user_groups table directly will
now need to skip over rows with ug_expiry < wfTimestampNow(). See
UsersPager for an example of how to do this.
NULL is used to represent infinite (no) expiry, rather than a string
'infinity' or similar (except in the API). This allows existing user group
assignments and log entries, which are all infinite in duration, to be
treated the same as new, infinite-length memberships, without special
casing everything.
The whole thing is behind the temporary feature flag
$wgDisableUserGroupExpiry, in accordance with the WMF schema change policy.
The opportunity has been taken to refactor some static user-group-related
functions out of User into UserGroupMembership, and also to add a primary
key (ug_user, ug_group) to the user_groups table.
There are a few breaking changes:
- UserRightsProxy-like objects are now required to have a
getGroupMemberships() function.
- $user->mGroups (on a User object) is no longer present.
- Some protected functions in UsersPager are altered or removed.
- The UsersPagerDoBatchLookups hook (unused in any Wikimedia Git-hosted
extension) has a change of parameter.
Bug: T12493
Depends-On: Ia9616e1e35184fed9058d2d39afbe1038f56d7fa
Depends-On: I86eb1d5619347ce54a5f33a591417742ebe5d6f8
Change-Id: I93c955dc7a970f78e32aa503c01c67da30971d1a
Adds support for tagging log entries for the block, import,
managetags, and move API modules, using a 'tags' parameter.
Bug: T97720
Change-Id: I9d75d2cece317a7704c4bc6d734ad3cafe24544e
Title::moveSubpages() sometimes returns a single message-specifier array
and sometimes returns an array of such arrays. This is extremely
difficult for a caller to deal with. Since nothing in Gerrit other than
ApiMove calls this, let's just fix it.
Also, it seems that messages were never created for the errors returned
by this method. So let's create them.
Change-Id: I4e55483c4476a1bb96c87266a4661871776fbf9b
Most of these are simply changing annotations to reflect
reality. If a function can return false to indicate failure
the @return should indicate it.
Some are fixing preg_match calls, preg match returns 1, 0 or false,
but the functions all claim to return booleans.
This is far from all the incorrect return types in mediawiki, there
are around 250 detected by phan, but have to start somewhere.
Change-Id: I1bbdfee6190747bde460f8a7084212ccafe169ef
It looks like there is something missing after the last statement
Also remove some other empty lines at begin of functions, ifs or loops
while at these files
Change-Id: Ib00b5cfd31ca4dcd0c32ce33754d3c80bae70641
This is one of the top three DB queries showing up in xenon
reverse flamegraph profiling.
It works via a per-wiki check key that is bumped whenever
someone changes a .js or .css page on that wiki.
Change-Id: I73f419558864ba3403b4601a098f6aaf84a3e7c1
It is possible for page restrictions to be dependent upon the content
model a page. The best example of this is user JavaScript and CSS
subpages. This adds a Title::setContentModel() function which allows
mocking a Title's content model for the purpose of permission checks.
EditPage and Special:ChangeContentModel were updated to ensure the user
can edit the page with the newly proposed content model before making
the change.
Title::$mContentModel was made private to make sure nothing else mucks
around with it. There were no uses outside of Title anyways.
Bug: T145316
Change-Id: I28c46f408cadf65ed1868401cd00dc15e5acd2fe
Queries from parsing are the top use of selectRow() according
to reverse flame graphs on xenon. This does not bother with
pages in namespaces less likely to be included.
Change-Id: Ica5d6e52c830cd71effff21933b8c64691082c11
This is more consistent with LoadBalancer, modern, and inclusive
of master/master mysql, NDB cluster, and MariaDB galera cluster.
The old constant is an alias now.
Change-Id: I0b37299ecb439cc446ffbe8c341365d1eef45849
Does both Title and user related methods, so it catches things that only
call $wgUser->isAllowed( 'read' ), as well as giving a nicer error message
for things that use $title->userCan().
Otherwise, the user can still do stuff and read pages if they have an
ongoing session.
Issue reported by Multichill
Bug: T129738
Change-Id: Ic929a385fa81c27cbc6ac3a0862f51190d3ae993
Special:UserLogout should be whitelisted, if Special:UserLogin is whitelisted,
as otherwise the user is able to login, but not able to logout anymore (given,
that the sys-admin hasn't change the $wgWhitelistRead config variable).
Special:ChangePassword redirects to Special:ChangeCredentials. Instead of
adding this special page, it should be done explicitly in the
wiki configuration (LocalSettings.php). For this reason, the whitelist is
removed, too.
Change-Id: I271efb517bf0ec0022e6fe29673570ca08e8fe1a
This made sense back in php4, but has no useful effect anymore
with our minimum php version being 5.5. This also has the effect
of searching for 'function makeTitle' now actually finding something.
Change-Id: I0ea02a2e7dff285341b0e5b5b7773da78bfaaff3
* This puts the complex logic here after the commit step for
all DBs, making the main multi-DB transaction more likely
to be atomic.
* Made some cleanups to AtomicSectionUpdate and made it cancel
if the transaction is rolled back as it should.
* Also cleaned up some closures for PHP 5.4.
Change-Id: If2f7bb6b1ba6daf1cfdc934f27c32b0b10431a3d