There are a couple of user options related classes already,
and the T321527 work on dynamic defaults is going to add
even more. Let's move them into a separate namespace
to make core a bit more organized.
Old name is kept as an alias for compatibility purposes.
Bug: T321527
Bug: T352284
Change-Id: I9822eb1553870b876d0b8a927e4e86c27d83bd52
Support migration stages when reading and writing blocks.
I tried to set it up for an easy next stage, in which support for the
old schema is removed. I tried to avoid factoring out of shared code
between the two schemas, so that the old schema cases can simply be
deleted without the need to revert unnecessary abstractions.
However, I added HideUserUtils to factor out ipb_deleted queries. Code
review showed that this was already quite complex, with multiple
approaches to the problem, so it benefits from refactoring even without
the schema abstraction.
HideUserUtils is a service rather than a standalone class to support
unit tests, since unit tests do not allow global config access. When
the migration stage config is removed, it will be a service with no
constructor parameters -- an unnecessary abstraction which should
ideally be resolved at that time.
When interpreting result rows, it is possible to share code by using
field aliases. But when constructing WHERE conditions, the actual field
names need to be used, so the migration is more intrusive in
ApiQueryBlocks and SpecialBlockList, where complex conditions are used.
Bug: T346293
Bug: T51504
Bug: T349883
Change-Id: I408acf7a57b0100fe18c455fc13141277a598925
This allows extensions and hooks to pass around additional data
about the operation result arbitrarily to supplement value and errors.
When two StatusValue instances are to be merged, it's responsibility
of the caller to ensure either only one has this extra data or none,
but never both (since the type is unrestricted). If necessary, the
caller should merge them before invoking StatusValue::merge.
Bug: T326479
Change-Id: Ibe3f1f8b81bcfcb18551d3ca4cda464e4bdbcbce
Why:
Temporary accounts (introduced as part of IP Masking)
are supposed to expire 1 year after their registration.
Automatic account expiration can be done via a maintenance
script, which would be periodically executed via cron / systemd.
Make it possible for extensions to provide their own logic
for generating a list of temporary accounts to invalidate.
This is used in CentralAuth to base registration timestamp
on the global registration timestamp.
The default behavior is "temporary accounts do not expire",
given the feature requires a maintenance script to run
periodically, which will not be the case on third party
instances.
What:
* Add `expireAfterDays` to $wgAutoCreateTempUser, controlling
how many days temporary accounts have.
* Add UserSelectQueryBuilder::whereRegisteredTimestamp(),
filtering accounts based on user_registration.
* Add ExpireTemporaryAccounts maintenance script, which is
@stable to extend.
Bug: T344695
Change-Id: If17bf84ee6620c8eb784b7d835682ad5e7afdfcc
Remove the 'user' option from the documentation and defaults. It has
been ignored since a3b4881f6f (2021, 1.37).
Fix tests which pass unknown constructor options. I found these by
temporarily patching the constructor to throw when an unknown option is
given.
Change-Id: I95cb2a38a5688d83c90ad501786f6d6bb02765ba
* Migrate callers of DatabaseBlock methods newListFromTarget,
newFromID, newFromTarget, doAutoblock.
* Deprecate DatabaseBlock methods newFromID and getAutoblockExpiry.
These are the methods with no extension callers in code search.
Bug: T255433
Change-Id: If0358459f53d32e7fe984c2fb8b61e0088f28922
== Skin::wrapHTML ==
Skin::wrapHTML no longer has to perform any guessing of the
ParserOutput language. Nor does it have to special wiki pages vs
special pages in this regard. Yay, code removal.
== ImagePage ==
On URLs like /wiki/File:Example.jpg, the main output handler is
ImagePage::view. This calls the parent Article::view to handle most of
its output. Article::view obtains the ParserOptions, and then fetches
ParserOutput, and then adds `<div class=mw-parser-output>` and its
metadata to OutputPage.
Before this change, ImagePage::view was creating a wrapper based
on "predicting" what language the ParserOutput will contain. It
couldn't call the new OutputPage::getContentLanguage or some
equivalent as Article::view wouldn't have populated that yet.
This leaky abstraction is fixed by this change as now the `<div>`
from ParserOutput no longer comes with a "please wrap it properly"
contract that Article subclasses couldn't possibly implement correctly
(it coudln't wrap it after the fact because Article::view writes to
OutputPage directly).
RECENT (T310445):
A special case was recently added for file pages about translated SVGs.
For those, we decide which language to use for the "fullMedia" thumb
atop the page. This was recently changed as part of T310445 from a
hardcoded $wgLanguageCode (site content lang) to new problematic
Title::getPageViewLanguage, which tries to guestimate the page
language of the rendered ParserOutput and then gets the preferred
variant for the current user. The motivation for this was to support
language variants but used Title::getPageViewLanguage as a kitchen
sink to achieve that minor side-effect. The only part of this
now-deprecated method that we actually need is
LanguageConverter::getPreferredVariant().
Test plan: Covered by ImagePageTest.
== Skin mainpage-title ==
RECENT (T331095, T298715):
A special case was added to Skin::getTemplateData that powers the
mainpage-title interface message feature. This is empty by default,
but when created via MediaWiki:mainpage-title allows interface admins
to replace the H1 with a custom and localised page heading.
A few months ago, in Ifc9f0a7174, Title::getPageViewLanguage was
applied here to support language variants. Replace with the same
fix as for ImagePage. Revert back to Message::inContentLanguage()
but refactor to inLanguage() via MediaWikiServices::getContentLanguage
so that LanguageConverter::getPreferredVariant can be applied.
== EditPage ==
This was doing similar "predicting" of the ParserOutput language to
create an empty preview placeholder for use by preview.js. Now that
ApiParse (via ParserOutput::getText) returns a usable element without
any secret "you magically know the right class, lang, and dir" contract,
this placeholder is no longer needed.
Test Plan:
* EditPage: Default preview
1. index.php?title=Main_Page&action=edit
2. Show preview
3. Assert <div class="mw-content-ltr mw-parser-output" lang=en dir=ltr>
* EditPage: JS preview
1. Preferences > Editing > Show preview without reload
2. index.php?title=Main_Page&action=edit
3. Show preview
4. Assert <div class="mw-content-ltr mw-parser-output" lang=en dir=ltr>
5. Type something and 'Show preview' again
6. Assert old element gone, new text is shown, and new element
attributes are the same as the above.
== McrUndoAction ==
Same as EditPage basically, but without the JS preview use case.
== DifferenceEngine ==
Test:
1. Open /w/index.php?title=Main_Page&diff=0
(this shows the latest diff, can do manually by viewing
/wiki/Main_Page, click "View history", click "Compare selected revisions")
2. Assert <div class="mw-content-ltr mw-parser-output" lang=en dir=ltr>
3. Open /w/index.php?title=Main_Page&diff=0&action=render
4. Assert <div class="mw-content-ltr mw-parser-output" lang=en dir=ltr>
== Special:ExpandTemplates ==
Test:
1. /wiki/Special:ExpandTemplates
2. Write "Hello".
3. "OK"
4. Assert <div class="mw-content-ltr mw-parser-output" lang=en dir=ltr>
Bug: T341244
Depends-On: Icd9c079f5896ee83d86b9c2699636dc81d25a14c
Depends-On: I4e7484b3b94f1cb6062e7cef9f20626b650bb4b1
Depends-On: I90b88f3b3a3bbeba4f48d118f92f54864997e105
Change-Id: Ib130a055e46764544af0f1a46d2bc2b3a7ee85b7
… or with $this->fail() from the PHPUnit TestCase base class.
I hope this makes the code more readable, i.e. communicate the
intention better. The output should be the same, i.e. the test fails
as before in case of an error.
Change-Id: Ied8a045141ac92d6af6398682bb5d9ca7ca88c49
Previously, all kinds of permission errors were reported as "rate limit
exceeded".
Follow-Up-To: I9fee34f5b44e947a00f1aaf2d28202d009e2caec
Change-Id: Idec70e754bff265c4293aee37c600e54ed1aed40
None of these tests are using the doUserEditContent param as intended.
This is only for undos, not for indicating the parent revision.
Change-Id: I24a11fb7b960dfdc801b31207c2a55501e068e80
When ApiParse is used to parse a page containing numeric image links
like [[File:1]], those image links are returned in the "images" section
as numbers, not strings. This is due to a longstanding PHP feature where
numeric strings get converted into numbers when used as keys in an
associative array. So, coerce them back to strings.
While numeric image links seem rather useless, they still occur in the
wild, whether by design or by accident, and may break API consumers that
expect to deal with strings here.
Bug: T346265
Change-Id: I9bd3813afd1867d0ba9c7ef480ad5e6b062c1e94
The design principle for SelectQueryBuilder was to make the chained
builder calls look as much like SQL as possible, so that developers
could leverage their knowledge of SQL to understand what the query
builder is doing.
That's why SelectQueryBuilder::select() takes a list of fields, and by
the same principle, it makes sense for UpdateQueryBuilder::update() to
take a table. However with "insert" and "delete", the SQL designers
chose to add prepositions "into" and "from", and I think it makes sense
to follow that here.
In terms of natural language, we update a table, but we don't delete a
table, or insert a table. We delete rows from a table, or insert rows
into a table. The table is not the object of the verb.
So, add insertInto() as an alias for insert(), and add deleteFrom() as
an alias for delete(). Use the new methods in MW core callers where
PHPStorm knows the type.
Change-Id: Idb327a54a57a0fb2288ea067472c1e9727016000
> We lose useful coverage and spend valuable time keeping these tags
> accurate through refactors (or worse, forget to do so).
>
> I've audited each test to confirm it is a general test of the
> subject class, where adding any called methods would be an accepted
> change, thus widening it is merely a no-op that clarifies intent
> and reduces maintenance. I am not disabling the "only track coverage
> of specified subject" benefits, nor am I claiming coverage in
> in classes outside the subject under test.
>
> Tracking tiny details per-method wastes time in keeping references
> in sync during refactors, time to realize (and fix) when people
> inevitably don't keep them in sync, time lost in finding uncovered
> code to write tests for only to realize it was already covered but
> not yet claimed, etc.
@note: Motivated by patches like these from Krinkle from time to time,
see: I133c7b707aab7ceb4f2ecd3be38bd4bd1b194143 for example.
Change-Id: Icff4b5a2e9ce2108c1653052624c76004048cc31
This class is used heavily basically everywhere, moving it to Utils
wouldn't make much sense. Also with this change, we can move
StatusValue to MediaWiki\Status as well.
Bug: T321882
Depends-On: I5f89ecf27ce1471a74f31c6018806461781213c3
Change-Id: I04c1dcf5129df437589149f0f3e284974d7c98fa
UTPage is a badly named page that should not be used directly. In fact,
soon it will no longer be guaranteed to exist (T342428). Tests should
create the fixtures they need, using titles/summaries that are actually
meaningful and that make it easy to identify what test is responsible
for creating a given page.
In ApiSetNotificationTimestampIntegrationTest, make separate assertions
because the order of the two pages in the result set is not stable
(ApiPageSet::initFromTitles has no ORDER BY).
Change-Id: Iecfb75e16deaa2f682afd916f58d8c548ee1cbac
Mock the needed dependencies to avoid database access when possible, and
add the test to the Database group otherwise.
Bug: T155147
Change-Id: Ic5c39ab35ab4d993721713285180f072497a5a40
Mock the relevant services that need the DB instead, when possible. When
not possible, e.g. because DB access is needed for the test to make
sense, add the test to the Database group instead.
Change-Id: Iefbfe00bedc243906c6b860572568343268646cc
When no PARAM_HELP_MSG is set, the code builds a dynamic message key in
ApiBase::getFinalParamDescription, check the possible message as well
To make core tests pass in ApiFeedWatchlist the PARAM_HELP_MSG must be
always set
Depends-On: Iedb4f9d9f53a06d0ff8c11309de6c546182f752e
Depends-On: If490db5eef5db8fef349cd287232a409ae2dc85f
Depends-On: Ief80d8524472051fc03aec75047fc7a2127aab26
Depends-On: I74d2575de9765d69d967a0760a10b735eb811eca
Depends-On: Ib18c90b71d586750beb80171cc8109322e87bd92
Depends-On: Ia6e63188e3776476d401c8c2f266a370aa35a3bf
Depends-On: Iffed1a77f9267d382abaeffe533e577fca6a2844
Depends-On: I0f548b47121e07dd4199428d015df3da85166843
Change-Id: Id1a42b4a7742b96bdc9a55703a225d23c04d2991
Parsing titles is expensive, it happens in the test function itself via
Title::newFromText and also the called editPage() needs to parse the
title, better to pass the title object there.
Title::newFromText has a cache, that share the title object between the
api code and the test code.
Use independent title objects for testing. This requires some
Title::READ_LATEST to ensure the changed database after the api call is
used.
Change-Id: I00c14e270a5f4078f80d78696ca2e39acf138e95
TestUser creates the user and therefore needs the database. Avoid using
it in non-database tests.
Add ApiQueryBlockInfoTraitTest to the Database group because it needs
the database.
Add DeleteUserEmailTest to the Database group because since 3bedffa8
the default user is not created any more in non-database tests
Change-Id: Iff438964dde47a47a2fa4a314d55010bd8c7fee5