Once the Revision class is hard deprecated, we will still need to
run hooks that use Revision objects; even though the hooks will be
deprecated, Revision objects still need to be created for them.
To ensure that deprecation warnings aren't triggered by creating
Revision objects in deployed code, for deprecated hooks only
create the Revision object if the hook is registered.
All hooks that pass Revision objects have already been hard deprecated.
Bug: T246284
Change-Id: I7e718551822825cd390662bb201dd13e2e527e8b
Three new checks are now applied to user signatures in preferences:
* Disallow invalid HTML and lint errors (T140606)
Since 15e0e9bb4b we can rely on Parsoid to check the signature for
lint errors. (The old PHP Parser doesn't have this capability.)
Most importantly, this will disallow unclosed HTML tags. Unclosed
formatting tags like `<i>` (and also wikitext markup like `''`)
could affect the entire page with the bad markup.
New configuration variable $wgSignatureAllowedLintErrors is added
to allow ignoring some errors. The default value ignores the
'obsolete-tag' error (caused by HTML tags like `<font>` and `<tt>`.)
* Require a link to user page, talk page or contributions (T237700)
Various tools don't work correctly when such a link is missing. For
example, Echo notifications are not sent, DiscussionTools will not
allow replying to these comments, English Wikipedia's SineBot treats
these comments as unsigned.
Such requirement has been present for a long time in many Wikimedia
wikis' policies, but it was not enforced by software.
* Disallow "nested" substitution in signature (T230652)
Clever abuse of "subst" markup and tildes allows users to save edits
containing wikitext in which substitution occurs again when the page
is next saved. Disallow this in signatures, at least.
New configuration variable $wgSignatureValidation is added to control
what we do about the result of the validation described above. The
options are:
* 'warning':
Only displays a warning near the field on Special:Preferences if
the current signature is invalid. Signatures can still be changed
regardless of validity and will be used when signing comments.
* 'new':
In addition to the above, if a user tries to change their signature,
the new one must be valid. Existing invalid signatures are still
used when signing comments.
* 'disallow':
In addition to the above, existing invalid signatures are no longer
used when signing comments.
Bug: T140606
Bug: T237700
Bug: T230652
Change-Id: I07c575c2d9d2afe7a89c4847d16ac044417297bf
Deprecating something means to say something nasty about it, or to draw
its character into question. For example, "this function is lazy and good
for nothing". Deprecatory remarks by a developer are generally taken as a
warning that violence will soon be done against the function in question.
Other developers are thus warned to avoid associating with the deprecated
function.
However, since wfDeprecated() was introduced, it has become obvious that
the targets of deprecation are not limited to functions. Developers can
deprecate literally anything: a parameter, a return value, a file
format, Mondays, the concept of being, etc. wfDeprecated() requires
every deprecatory statement to begin with "use of", leading to some
awkward sentences. For example, one might say: "Use of your mouth to
cough without it being covered by your arm is deprecated since 2020."
So, introduce wfDeprecatedMsg(), which allows deprecation messages to be
specified in plain text, with the caller description being optionally
appended. Migrate incorrect or gramatically awkward uses of wfDeprecated()
to wfDeprecatedMsg().
Change-Id: Ib3dd2fe37677d98425d0f3692db5c9e988943ae8
There's already a thing called magic words, and this is not it. These
things are called variables. There are many usages of this term in the
source. The term was introduced by Lee in 2002: originally
OutputPage::replaceVariables() contained only this functionality.
I introduced the term "magic word", meaning a localizable keyword.
Localizable keywords are an abstraction not limited to this use case.
"Magic variables" is a neologism, but I suppose it is permissible, since
it disambiguates. Whereas calling a variable a magic word conflates rather
than disambiguates.
Fix terminology in magicword.md and update the examples.
Change-Id: I621c888e3790a145ca9978f6b30ff1a8f685b64c
The `false` return has been the source of persistent bugs (T253725,
T251952); lets nip this pattern in the bud before we release these new
APIs.
It would be nice to fix Parser::statelessFetchRevisionRecord() as well,
but that was released in 1.34, so it's not quite as easy to change.
Change-Id: I05a968e3dfb660d0709a6417d1d53a1d08ed4818
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.
General principles:
* Use DI if it is already used. We're not changing the way state is
managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
is a service, it's a more generic interface, it is the only
thing that provides isRegistered() which is needed in some cases,
and a HookRunner can be efficiently constructed from it
(confirmed by benchmark). Because HookContainer is needed
for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
SpecialPage and ApiBase have getHookContainer() and getHookRunner()
methods in the base class, and classes that extend that base class
are not expected to know or care where the base class gets its
HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
getHookRunner() methods, getting them from the global service
container. The point of this is to ease migration to DI by ensuring
that call sites ask their local friendly base class rather than
getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
methods did not seem warranted, there is a private HookRunner property
which is accessed directly. Very rarely (two cases), there is a
protected property, for consistency with code that conventionally
assumes protected=private, but in cases where the class might actually
be overridden, a protected accessor is preferred over a protected
property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
global code. In a few cases it was used for objects with broken
construction schemes, out of horror or laziness.
Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore
Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router
setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine
Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
This behavior has been deprecated and with a tracking category since
1.28. Time to remove the temporary parameter added to
Sanitizer::removeHTMLtags() and (finally) tweak the behavior to match
HTML5.
Bug: T134423
Change-Id: I5c725175d05854139c95a2b3d8d35ff63cb6707b
This is a follow up to I3eae3719ab8fb50b7996d4fd8a9fa0d5ca250023 where
it was moved below doBlockLevels.
This puts it next to the other call to the sanitizer and aligns it
closer with the idea of a post-processing pass in Parsoid.
Bug: T197879
Change-Id: I8ba4934c01a24d53d4871b8efa1e9cf737ba9ebd
Parser::getRevisionRecordObject() returns `null` if the revision is
missing, but it invokes ParserOptions::getCurrentRevisionRecordCallback()
(ie, Parser::statelessFetchRevisionRecord() by default) which returns
`false` as its error condition.
This reverts commit ae74a29af3, and instead
fixes the bug at its root.
Bug: T251952
Change-Id: If36b35391f7833a1aded8b5a0de706d44187d423
In the new hook system, it is invalid to have two hooks that differ only
in case.
This reverts commit afb5b38e15.
Change-Id: I160ece0a7bc68c748037b383137364b787be86a0
This was moved before doBlockLevels in c23cb2c when it used to be a more
general cleanup that conflicted with it. Since 02ff859 that no longer
seems necessary.
Further, this gives the consistency of armoring inside wikilinks and
avoids some unnecessary row definition list colons being armored.
Maybe this should be moved to the end of internalParseHalfParsed after
language conversion but before tidying, where the other call to the
sanitizer happens, Sanitizer::normalizeCharReferences. But let's change
things one step at a time and start by moving it here before we try to
move it further.
The goal here being to make french space armoring a post-processing
step, rather than an intermediate transformation, more consistent with
how Parsoid will/wants to do it.
Bug: T197879
Change-Id: I3eae3719ab8fb50b7996d4fd8a9fa0d5ca250023
This will allow us to deprecate the ParserBeforeStrip and ParserAfterStrip
hooks by covering the one case where ParserBeforeStrip is called but
ParserBeforeInternalParse is not.
Bug: T250450
Change-Id: Ia298fecba77e97fc30dc30a09ac69a4239767d8c
Originally we created a Parser object on every request, and so care
was taken to make Parser construction lightweight. In particular,
all potentially costly initialization was moved into a separate
Parser::firstCallInit() method. Starting with 1.32, parser construction
has instead been done lazily, via the ParserFactory registered with
MediaWikiServices. The extra complexity associated with the old manual
lazy initialization of Parser is therefore no longer needed.
Deprecate Parser::firstCallInit() as part of a general plan to refactor
the Parser class to allow subclasses and alternate parser implementations.
Add some tests to assert that parsers are being created lazily, and are
not being created when they are not needed.
Bug: T250444
Change-Id: Iffd2b38a2f848dad88010d243250b37506b2c715
This was overlooked in a5afda55bf, probably
because casual inspection of
https://codesearch.wmflabs.org/deployed/?q=mVariables&i=nope&files=&repos=
made it look like extensions/AbuseFilter was using Parser::$mVariables.
But AbuseFilterParser (and AbuseFilterCachingParser) is its own thing, not
a subclass of Parser, and the (re)use of the $mVariables name for the
property is just coincidence.
Change-Id: I4debb11c804b2ef4f1b727d521f38f35de691708
The following Parser methods were deprecated in favor of new methods:
- ::fetchCurrentRevisionOfTitle (use fetchCurrentRevisionRecordOfTitle)
- ::statelessFetchRevision (use statelessFetchRevisionRecord)
- ::getRevisionObject (use getRevisionRecordObject)
The following ParserOptions methods were likewise deprecated:
- ::getCurrentRevisionCallback (use getCurrentRevisionRecordCallback)
- ::setCurrentRevisionCallback (use setCurrentRevisionRecordCallback)
To ensure backwards compatibility with calling the ParserOptions
CurrentRevisionCallback methods, while allowing extensions to call
the CurrentRevisionRecordCallback methods without worrying about if
other extensions also deployed have been updated, both
::getCurrentRevisionCallback and ::getCurrentRevisionRecordCallback,
if the respective option is still set to the default, check if the
other option is set and, if it is, convert the other option rather
than returning thed default.
It's not pretty, but it works, and will be hard deprecated shortly
and removed in 1.36.
Bug: T249384
Change-Id: I66cbcb963a96cc49c75ca72faa7e439ae6d6614d
Parser::Options(), Parser::OutputType(), and Parser::Title() have been
deprecated. All of these had incomplete replacements with either a
::get* method or a ::set* method (and in the case of Title, both).
Add the missing getters or setters where required.
Only Parser::Title() has been hard deprecated. Replacing the other
uses in deployed code requires the newly-added Parser::getOutputType()
or Parser::setOptions() methods, so we can't replace those methods in
our deployed code after this patch has been merged.
Code search:
https://codesearch.wmflabs.org/deployed/?q=-%3E%28OutputType%7CTitle%7COptions%29%5C%28&i=nope&files=&repos=
Bug: T236809
Change-Id: I0b4d5f170216597afb259cedbb13b8028d284715
This setting has been effectively constant since 2008. In modern code
we should be using a ParserFactory instead to customize Parser creation
and not calling the Parser constructor directly (T236811).
Because the ParserFactory is cached, which freezes the current value of
the content language and other options, we need to reset the ParserFactory
object when running parser tests (T248977). Thanks to
Peter Ovchyn <peter.ovchyn@speedandfunction.com> for first uncovering this
issue and suggesting a fix in I4203bf7719a8555a09b72cdb5b1ae7a6e1505acf.
Code search:
https://codesearch.wmflabs.org/deployed/?q=wgParserConf&i=nope&files=&repos=https://codesearch.wmflabs.org/deployed/?q=ParserConf&i=nope&files=&repos=
Bug: T248977
Bug: T236811
Depends-On: I97d58750c91b06eeca5d810509becdf53a39cc95
Depends-On: Idf59cd54146d31c1c32883f4318e6a0bf60e1a8a
Change-Id: I787f22ea9bf59a049b13631ba6974866a1300988
Disabling tidy has been deprecated since 1.33. This cleans up the code
paths which still used untidy output.
Bug: T198214
Change-Id: I821ef3b8f59b272d983583d407b2f0794fe1e791