* Remove the mention of 'return true' being legal.
This is only allowed for compat with code from before MW 1.21,
when I added hook aborting as well as tolerance for null to
be the same as true.
Since then, there is no reason to return null or return true.
For early returns, an explicitly void 'return;' should be used
instead. Returning anything else like null/true serves no purpose
other than to confuse the reader.
* Mark the interfaces as natively 'void' with return type hints.
This means in core code that runs the hook, static analysis
like Phan and in IDEs, it will be known that these onFoo()s
never return a value, thus allowing them to detect if its
return value is assigned or used in a conditional for any
reason, which can be an easy mistake.
It also means that in the future when extensions start using
these interfaces in 'implements' statement, they will be
required to mark their hooks as void.
That migration is opt-in and still up ahead. This is not
a breaking change even for all existing extensions where
a return true/null may exist in an abortable hook since this
only applies to code directly typed against the interface.
The internal run() method doesn't care.
Change-Id: Ib79289bd486ac97cec492e72f9a8dee70cf2f6c2
WikiPage::doRollback modifies $details to include Revision objects,
and while the method has been marked as internal and will have breaking
changes made in 1.36 to remove the use of Revision objects entirely,
for now they should not be used, but rather their RevisionRecord objects
retrieved instead.
Bug: T251853
Change-Id: Ie907af06774a3980d506c9f089b0122f36cda7bf
Yes, the methods are all deprecated, as is using that API path, but
until they can be removed we can at least reduce the use of $wgUser
Bug: T243708
Change-Id: I34df7dc3b1c3b1258d3bd3dca4bdb261124004cd
This method was recently added and was to result in the deprecation
of a few places where User objects were being passed to the factory.
This has now been reconsidered and this patch reverts to the
previous behaviour. It is largely a revert of Ie1bed9e9537cabc836992ccfa7fb127885ea3e11
Bug: T238466
Depends-On: Idc9f33fd5ab55bde88cc306ca63adead286380a8
Change-Id: I3653559704ccfd9bca0946f5a865be93bdf5ceb6
A terminating line break has not been required in wfDebug() since 2014,
however no migration was done. Some of these line breaks found their way
into LoggerInterface::debug() calls, where they mess up the formatting
of the debug log.
So, remove terminating line breaks from wfDebug() and
LoggerInterface::debug() calls.
Also:
* Fix the stripping of leading line breaks from the log header emitted
by Setup.php. This feature, accidentally broken in 2014, allows
requests to be distinguished in the log file.
* Avoid using the global variable $self.
* Move the logging of the client IP back to Setup.php. It was moved to
WebRequest in the hopes that it would not always be needed, however
$wgRequest->getIP() is now called unconditionally a few lines up in
Setup.php. This means that it is put in its proper place after the
"start request" message.
* Wrap the log header code in a closure so that variables like $name do
not leak into global scope.
* In Linker.php, remove a few instances of an unnecessary second
parameter to wfDebug().
Change-Id: I96651d3044a95b9d210b51cb8368edc76bebbb9e
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 data is the same as the 'credits' data that is already compiled,
cached and made available via ExtensionRegistry.
Similar to various other configuration variables previously, the
$wgExtensionCredits variable is now also required to only be used
for providing input to the system (e.g. from LocalSettings.php,
or from legacy extension PHP entry points). It is no longer
supported to use this variable to reliably read out a full view
of all extension credits (specifically those registered via
extension.json).
Doing so had the downside of adding processing cost to every
web request, as well as taking one the single largest portion
of the ExtensionRegistry APCu cache key, which in PHP7+ incurs
a linear cost for every string value, string key, of every
(sub)array in this huge structure; and does to on every request
just in case something reads from $wgExtensionCredits.
The new method to access this information reliably is owned
by SpecialVersion for now (could be moved elsewhere). This
also makes the merging logic more testable and incurs it on-demand
rather than upfront.
Details:
* Move 'type' internally from NOT_ATTRIBS to CREDIT_ATTRIBS.
These two arrays behave identically for most purposes (they are
both used to mean "don't export this as a global attribute").
By placing it in CREDIT_ATTRIBS it becomes complete and makes
it easy to refer to in docs. Previously, extractCredits()
read the 'type' key outside the loop for CREDIT_ATTRIBS.
* Remove redundant code in ApiBase.php, that is now more obviously
redundant. Looks like a left-over or merge conflict mistake
from when ExtensionRegistry was first introduced.
Bug: T187154
Change-Id: I6d66c58fbe57c530f9a43cae504b0d6aa4ffcd0d
Introduces $wgWatchlistExpiryMaxDuration which is used instead of given
expiry if the given exceeds it. This is done in the storage layer. The
reasoning is to control the size of the watchlist_expiry table. Hence,
the max duration does not apply to indefinite expiries (since that would
mean now row in watchlist_expiry).
The frontend is responsible for disallowing expiries greater than the
max, if it choses to do so.
APIs should now pass in $wgWatchlistExpiryMaxDuration as the PARAM_MAX
setting for the 'expiry' type. They should also set PARAM_USE_MAX so
that the maximum value is used if it is exceeded.
Other APIs that watch pages will be updated in separate patches
(see T248512 and T248514).
Bug: T249672
Change-Id: I811c444c36c1da1470f2d6e185404b6121a263eb
Make sure that CAUGHT_BY_HANDLER is only for errors caught by the
handler from MWExceptionHandler::installHandler().
Add CAUGHT_BY_ENTRYPOINT constant for entrypoint try/catch logic,
e.g. MediaWiki::run()/ApiMain::executeActionWithErrorHandling().
Use Throwable to catch more types of errors given that PHP 7.2
is already required.
Change-Id: Ib496e26572c98d771a772972676c02c05b872e31
Add a new setUser() method to PreferencesFactory so that a User
object doesn't have to be passed around so much. This is how
GlobalPreferencesFactory has done it, and so after this change
that code can be removed from GlobalPreferences.
Bug: T238466
Change-Id: Ie1bed9e9537cabc836992ccfa7fb127885ea3e11
This was previously making calls to various methods during the
Setup.php, which apart from being deferrable logic that isn't
needed on most requests, is also risky/complicated because MW
isn't initialised yet at this point.
Bug: T189966
Change-Id: Iaee3f2af8d18bc5095e9297cbe1b6efc627f3977
These classes implement hook interfaces, providing implementations which
proxy calls to HookContainer::run().
To reduce the size of the HookRunner class, I split it into two parts:
one for the API and one for everything else. The API was the largest
identifiable component, and this matches the way we modularize i18n
files.
These two classes were originally generated by the hook interfaces
script. I've added abortable options for hooks that were
called with runWithAbort().
Bug: T240307
Change-Id: Id6789070bf830ecea271ddc74fa929e0bd39356d