Commit graph

68 commits

Author SHA1 Message Date
Kunal Mehta
0ec8125642 registration: Catch correct exception type from ObjectCache
ObjectCache::newFromId() now throws an InvalidArgumentException if the
specific id can't be found.

Change-Id: Idcb0f2158a38555c1ec1681ba0635c7903e48718
2018-06-11 21:09:47 +00:00
Ed Schouten
d7d5d3c82a registration: Allow the mtime of extension.json files to be zero
When creating Docker images of MediaWiki using the Bazel build system, I
noticed that I'm not able to load any extensions. This is due to the
fact that Bazel always generates container layers with mtimes of files
set to 1970-01-01 for determinism/reproducibility.

Relax the check a bit to only fail when the mtime is false, which
happens when filemtime() fails.

Bug: T196672
Change-Id: Ieaeb3113a7d9c44f29cca2d062c5bb11ebeada0d
2018-06-07 10:58:40 -07:00
Antoine Musso
224864ebdd registration: Initialize PSR-4 namespaces at same stage as normal autoloader
readFromQueue() injects the content of AutoloadClasses to
$wgAutoloadClasses however it missed doing the same for
AutoloadNamespaces.

When using the installer with an extension having AutoloadNamespaces
set, its classes would not be found.

Make ExtensionRegistry append to AutoLoader::$psr4Namespaces, and add
a test to cover the new behavior.

Bug: T195783
Change-Id: Id61155867a4ca7d9bc4a347f8671da74b0fa490b
2018-05-30 13:07:42 -07:00
Max Semenik
69aecc2eea Don't initialize MediaWikiServices before extensions have been loaded
Bug: T153256
Bug: T190425
Change-Id: I749f66d13a8c8a8ae4a83661b83c56f0db74a187
2018-05-03 23:36:10 -07:00
Kunal Mehta
c8833d8e8e Handle extension dependencies in the installer
As there will likely be extensions bundled with the 1.31 release that
depend upon other extensions, we should have the installer prevent users
from enabling extensions that depend on other, not-enabled extensions.

We can build a dependency map from extension.json's "requires"
component. On the client-side, we'll first disable all checkboxes that
require other extensions, and evaluate each checkbox click, updating the
disabled checkboxes as possible.

This required some refactoring of how ExtensionRegistry reports issues
with dependency resolution so we could get a list of what was missing.

While we're at it, sort the extensions under headings by type.

This does not support skins that have dependencies yet (T186092).

Bug: T31134
Bug: T55985
Change-Id: I5f0e3b1b540b5ef6f9b8e3fc2bbaad1c65b4b680
2018-04-13 15:28:40 -07:00
Kunal Mehta
f492a981bf Improve ExtensionRegistry test coverage
Change-Id: I7f7445952f057995a3e3215145803affa5aceede
2018-02-12 20:36:50 -08:00
Kunal Mehta
77d37c2487 registration: Remove unused ExtensionRegistry::markLoaded
This is unused, and it would make more sense for whatever wants to add
credits to directly modify $this->loaded instead of incurring the
overhead of an extra function call.

Change-Id: Icce1a87d2dc8ce61cb05eace6e0b65d6cea4c58d
2018-02-12 20:43:48 +00:00
Umherirrender
0483765086 convertExtensionToRegistration: Set requires key in extension.json
The highest manifest version is not supported from the start of
extension.json
For extensions converted to this highest version the mininum core
version must be specified to avoid load problems in the extension.

Using 1.29.0 for manifest version 2 due to T149757 /
Id1071fc0647892438e5cd0e3ee621fbdaaa64014

Change-Id: Iea5ba589c70958db7500cf3587b5ebd738532026
2018-02-05 06:56:24 +00:00
Marius Hoch
cc433d1ff1 ExtensionRegistry: Properly detect if a global is already set
$foo = null; isset( $foo ); will yield false.

Sometimes we want to explicitly set a config to null, but ExtensionRegistry
is then overriding this variable with the default value.

This is no consistent with the old workflow:
require_once the extension and then override the setting with null.

Bug: T128661
Change-Id: I0654c9369a596e84591fcaa9643703e6b4ccf57e
2018-01-23 10:44:28 -08:00
mainframe98
70e92cdad5 Fix additional usage of incorrect case
Courtesy of the PhpStorm inspection Case mismatch in method call or
class usage.

Bug: T166759
Change-Id: I27c53658b99048fa0dd8f9d6ef1398620386e1cc
2017-12-15 11:58:11 +01:00
Yifei He
b3840b25b3 Avoid using array_map in ExtensionRegistry and ExtensionProcessor for simple operations
Bug: T182645
Change-Id: Ia98b1d798b1f93ca30686c009d479668616229ae
2017-12-14 15:51:33 +00:00
Kunal Mehta
036f5b47ef Enable using PSR-4 autoloader for MediaWiki core and extensions
This adds support for a PSR-4 (<http://www.php-fig.org/psr/psr-4/>)
autoloader, so instead of needing to manually list each class, just the
namespace prefix is needed.

Extensions can set a "AutoloadNamespaces" property in extension.json to
register PSR-4 compatible namespaces to be autoloaded.

The implementation is based off of the example implementation
(<http://www.php-fig.org/psr/psr-4/examples/>) with some modifications
for performance, notably cutting down on function calls, and only trying
to look up classes that are namespaced.

The generateLocalAutoload.php script will ignore any directory that is
registered as a PSR-4 namespace.

Bug: T99865
Bug: T173799
Change-Id: Id095dde37cbb40aa424fb628bd3c94e684ca2f65
2017-12-12 00:20:11 +00:00
Kunal Mehta
72d92f6fe3 registration: Fix caching of load_composer_autoloader
Move the file_exists() check out of the extension processor and into the
extension registry so that it is evaluated at run time instead of during
caching. The prior way is problematic since we don't invalidate the
cache if the existence of the file were to change.

Bug: T176534
Change-Id: I98e4ffdfac9f98397a103966824519afe1375356
2017-09-22 22:20:16 -07:00
Umherirrender
ff5222b3a0 registration: Improve error message for invalid "callback" in extension.json
Getting the following error for an invalid callback is not helpful:
Warning: Invalid argument: function: class not found in
/includes/registration/ExtensionRegistry.php on line 335

Change-Id: I4dfc011cb0a5cd06f1836d73e58f407d468e4546
2017-09-09 00:07:07 +00:00
Umherirrender
be42e09aa8 build: Prepare for mediawiki/mediawiki-codesniffer to 0.9.0
The used phpcs has a bug, so the version 0.9.0 could not be enforced at the moment.
Will be fixed in next version, see T167168

Changed:
- Remove duplicate newline at end of file
- Add space between function and ( for closures
- and -> &&, or -> ||

Change-Id: I4172fb08861729bccd55aecbd07e029e2638d311
2017-06-26 17:14:31 +00:00
Kunal Mehta
d93a15f331 registration: Avoid deprecated wfMemcKey()
Change-Id: I8f4382d55ba2d006f1573e945c83c3fd541a2cb1
2017-05-23 21:01:09 -07:00
jenkins-bot
5891a2e733 Merge "registration: Move attributes out of the top level" 2017-05-16 04:00:28 +00:00
Kunal Mehta
fdb7e94104 registration: Move attributes out of the top level
This moves attributes out of the top level, and namespaces them under
each extension. If the extension that it belongs to is not installed,
the attribute is not exported and dropped.

The full name of the attribute is the name of the extension plus the
name of the attribute key. This enforces the recommendation that the
attribute name start with the extension's name.

Add test coverage for attributes under manifest_version 1 and 2.

Bug: T133627
Depends-On: I5a148763f68989c8da313a4fb1d0213658ee4495
Depends-On: I5a148763f68989c8da313a4fb1d0213658ee4459
Change-Id: I8613a027c56e2c9d2c6a83ca14749eb1c8fc23be
2017-05-15 20:09:50 -07:00
Kunal Mehta
a1c9182c58 registration: Deprecate not having manifest_version set
Emit a wfDeprecated() warning for each extension that does not have
manifest_version set.

Because we don't have any mechanism to cache warnings, just disable the
cache if any deprecation warnings are emitted. This ensures that the
warnings are shown on every page load instead of probably once a day.

Bug: T155610
Change-Id: I163a84ae1d381ca5bd67b4b317c04f9f51c066ea
2017-05-15 17:36:53 -07:00
Kunal Mehta
a6f172ef3c registration: Don't initialize MWServices super early
Previously, MediaWikiServices would be initialized on the first
wfLoadExtension() call, which is super early and before it should be.
There's actually no reason we need to create the BagOStuff object in the
constructor, so let's defer it to loadFromQueue(). It now gets called
from the top of Setup.php, which is still a little early, but better
than before.

Bug: T154960
Change-Id: I3feef3b974ba1ba3afec0d453e1899cd476e72fb
2017-01-10 10:47:08 -08:00
Kunal Mehta
90cfe33631 registration: Improve dependency checking
* Pass $coreVersion to VersionChecker's constructor, don't require a
setter.
* Bump ExtensionRegistry::CACHE_VERSION
* Return single strings from handle* functions, avoid array_merge calls
* Improve invalid version error message
* Fix naming of VersionCheckerTest class

Change-Id: Id4f66b815aa41dbbc4b966095d6b99e542e548b4
2016-12-15 15:09:26 -08:00
Florian Schmidt
90698a878b registration: Allow specifying extension dependencies
There are some extensoins that depend upon another extension or skin,
usually in different ways:
* A constant that is added in the dependency extension, and the
existence of is checked for. This is problematic because it requires a
specific load order.
* Checking whether a specific class exists. This is problematic because
it is extremely fragile, and breaks whenever the class is renamed.
* Checking ExtensionRegistry::isLoaded(). This is mostly there, but it
only checks at runtime, and doesn't provide any machine readable data.

Furthermore, developers implement each one differently, with very little
standardization.

With this, extensions may now specify what other extensions they depend
on. This is for explicit *hard* dependencies that must be installed.

For example:
	"requires": {
		"MediaWiki": ">= 1.25.0",
		"extensions": {
			"FakeExtension": "*"
		},
		"skins": {
			"FakeSkin": "*"
		}
	}

This would add a minimum requirement on MediaWiki 1.25.0+ (already
implemented), as well as the requirement that the FakeExtension extension
needs to be installed, as well as the FakeSkin skin. A wildcard (*) is
used instead of an explicit version requirement as many extensions do
not actually version themselves, and there is no consistent versioning
scheme yet.

Bug: T117277
Change-Id: If1cccee1a16a867a71bb0285691c400443d8a30a
2016-12-14 19:18:09 +01:00
Florian Schmidt
5f11f7818c registration: Generalize CoreVersionChecker to VersionChecker
This allows us to put other requirements more easily into extension
registration, such as skins and/or extensions.

Bug: T117277
Change-Id: I3ec1b28b6af380621585cd61b38e5ebb8be9f9c7
2016-12-14 19:18:09 +01:00
jenkins-bot
c26eb0f870 Merge "registration: Provide credits information to callbacks" 2016-12-06 19:07:01 +00:00
Florian Schmidt
5a855c8625 registration: Don't let extensions load late
We want all extensions to be queued together and load at the same time
so in the future we can properly evaluate dependencies as a whole. If
extensions load late, they would bypass this, potentially causing
issues.

Bug: T117277
Change-Id: I09b306bd6f6ccf4210f36be0118e7f17f2c3d264
2016-12-04 02:12:37 -08:00
Kunal Mehta
b54acaf847 registration: Provide credits information to callbacks
Registration callbacks now provide basic credits information (name,
path, type, authors, license-name, version, etc.) as the first argument.
The main use case right now for this is to support extension VERSION
constants for backwards-compatibility.

In addition, callbacks now run *after* attributes are exposed, so
callbacks could use data from them if they wanted to.

Bug: T151136
Change-Id: Ic5965dd4e259e1f46222ac92b8e78750e67b51d6
2016-12-04 02:15:01 +00:00
Reedy
934402b021 Check MW version requires before manifest_version
Bug: T149751
Change-Id: I914be4da431dcd613bdf2d1fd5ba9f28cf5b936b
2016-11-01 23:03:13 +00:00
Yuri Astrakhan
ab224f8211 Added array_replace_recursive merge strategy
For extension registry, add array_replace_recursive merge strategy,
as some extensions/configuration may prefer that to array_merge_recursive.

In some cases, configuration is merged from multiple extensions,
such as JsonConfig's $wgJsonConfigs configuration: ZeroBanner defines

	"JsonZeroConfig": {
		"namespace": 480,
		"nsName": "Zero",
		"isLocal": false,
		"cacheKey": "1"
	}

and mobile.php overrides it with
	$wgJsonConfigs['JsonZeroConfig']['isLocal'] = false;
	$wgJsonConfigs['JsonZeroConfig']['remote'] = [
		'url' => 'https://zero.wikimedia.org/w/api.php',
		'username' => $wmgZeroPortalApiUserName,
		'password' => $wmgZeroPortalApiPassword,
	];

Having identical value 'isLocal' would be converted into an array
if array_merge_recursive is used, but the replace strategy fixes it.

Change-Id: Ica6ddd0ae76f23e60de9b6235c6e2a3f2754a95d
2016-10-24 19:20:04 +00:00
addshore
c8042bb8cc Fix ExtensionRegistry cache doc that is out of date
Change-Id: If019599baec4e8c566362744c2f565ca169b66b6
2016-10-18 11:55:05 +01:00
Aaron Schulz
88aa91f84a Clean up some ObjectCache factory callers
* Use services container in more places.
* Undeprecated getLocalServerInstance() since $fallback is not
  handled elsewhere.

Change-Id: Id1fcd1c465d2d92653357523f4225f1c4d1ace2f
2016-10-03 11:44:55 -07:00
Kunal Mehta
83ec5909d4 registration: Convert "config" into an object with metadata
To add extra metadata for "config" options without constantly adding
hacky underscore prefixed keys, convert "config" items into an object,
where the value is under a "value" key.

"_merge_strategy" is now just "merge_strategy", but still has the
underscore prefix for the cache structure, to avoid changing it.

Since this is a fully breaking change, it only applies to files with
manifest_version: 2 set. A conversion script has been added to assist
with automated conversion.

Bug: T133626
Change-Id: Id1071fc0647892438e5cd0e3ee621fbdaaa64014
2016-07-13 14:58:00 -07:00
Florian
70f6f8865f registration: Load extra autoload files before executing callbacks
Callbacks should be able to safely assume that anything (or at least mostly)
defined in extension registration is already loaded and processed when
the callback itself is executed. To make sure, that this applies, callbacks
should be executed after all extra autoload paths are loaded.

Bug: T131978
Change-Id: I2c6624423957a8a00523b126fa7209d9c283aa9e
2016-04-06 22:33:18 +00:00
Bartosz Dziewoński
361b09576e Remove comments about isset( $string['foo'] ) being true on PHP 5.3
...but don't remove the code. Calling isset( $bar['foo'] ) without checking
that $bar is an array seems not very nice to me.

Change-Id: I822c925b6f36bf34902f8075e54f71fe4f6d2566
2016-02-17 20:12:30 +00:00
Kunal Mehta
6e9b4f0e9c Convert all array() syntax to []
Per wikitech-l consensus:
 https://lists.wikimedia.org/pipermail/wikitech-l/2016-February/084821.html

Notes:
* Disabled CallTimePassByReference due to false positives (T127163)

Change-Id: I2c8ce713ce6600a0bb7bf67537c87044c7a45c4b
2016-02-17 01:33:00 -08:00
Kunal Mehta
9db32681e4 registration: Handle $wgExtensionCredits inside the ExtensionProcessor
Bug: T108269
Change-Id: I92675dac5cca52448e24902d0a5c865fd6df46d9
2016-01-02 15:43:52 +00:00
victorbarbu
7489cdfc05 registration: Allow loading composer's autoloader if it exists
Extensions that have composer dependencies can set
 "load_composer_autoloader": true
to load "$dir/vendor/autoload.php" if it exists.

While it is recommended to use composer-merge-plugin to manage
composer dependencies for extensions, using a local autoloader
can be easier for development and is used by ExtensionDistributor.

Bug: T119766
Change-Id: Ib031bef17c8a7d708a5c7878e74967d19217bbc8
2015-12-29 23:20:17 +00:00
Aaron Schulz
17c91ad610 Replace newAccelerator() with getLocalServerInstance()
The name is clearer and more consistent, with simpler arguments.

Change-Id: I7205a99ce033e8b086a52cd02c8a721e99c84b1e
2015-11-02 21:39:08 +00:00
umherirrender
c572d18661 Fixed spacing
- Removed space after cast
- Removed spaces in array index
- Removed double spaces
- Added spaces around string concat
- Fixed mixed tabs and spaces at begin of line

Change-Id: I38e849723f055d2d4c05cba72f5c245a28e8d5da
2015-09-26 20:44:54 +00:00
Kunal Mehta
7abf99282d registration: Vary the loaded queue cache on $wgVersion
If the version changes, we need to recheck the dependency requirements.

Follows-up cef1f31167.

Change-Id: I30e95b5dec7b5a1d9ca391fb2ae55e0b3de0c528
2015-09-24 18:09:41 -07:00
jenkins-bot
35f61c7c4b Merge "registration: Allow extensions to specify which MW core versions they require" 2015-09-22 04:57:47 +00:00
Kunal Mehta
cef1f31167 registration: Allow extensions to specify which MW core versions they require
This adds a "requires" property to extension.json, which extensions and
skins can use to indicate which versions of MediaWiki core they support.
The hacky wfUseMW() is now deprecated in favor of this.

Rather than writing our own version constraint and parser library, we
can re-use composer's, which was recently split out into a separate
library named "composer/semver" for this patch.

Any syntax accepted by composer[1] is available for usage here. Test
cases have been provided to demonstrate how versions are parsed. For now
it is recommended that people stick to expressing compatability with
stable versions (e.g. ">= 1.26").

This patch does not support requiring specific MediaWiki core WMF
branches, since those do not follow the standard semver format that
composer parses. If we are unable to parse $wgVersion, all checking will
be skipped and reported as compatible.

[1] https://getcomposer.org/doc/01-basic-usage.md#package-versions

Bug: T99084
Change-Id: I7785827216e16c596356d0ae42d6b30f3f179f10
2015-09-21 09:56:53 -07:00
Kunal Mehta
0a83ef3cf7 registration: Fix merging of array_plus
We want the local configuration ($GLOBALS[$key]) to override the default
values ($val). This matches what `array_merge` does.

Bug: T112868
Change-Id: I9c333a1fa67d3f24e09ffed3072b2897389f6139
2015-09-17 10:29:02 -07:00
Florian
20f2df9c9f Implement wfArrayPlus2d which combines 2d arrays
Moved the logic of ExtensionRegistrations array_plus_2d merge method out
to it's own global function wfArrayPlus2d, so any other function in mediawiki
core and it's extensions can use this method when they need to union
a 2d array.

Change-Id: I56afdf306e399a4a1505828ed76c60c1bfd033b6
2015-09-01 20:53:54 +02:00
Timo Tijhof
79ce51d1c9 objectcache: Make first parameter of newAccelerator optional
Makes it more convenient to use.

Change-Id: I1e11f7a759bd2816e47d1c2453cbe39b8f44b2f0
2015-08-24 23:43:19 +02:00
Kunal Mehta
8cc0de98dd registration: Actually set the merge strategy for $wgExtensionCredits
$wgExtensionCredits is special and needs to be set in the
ExtensionRegistry. Also change the cache key so any bad cache entries
will be ignored.

Follows up 1ebb0f5659.

Change-Id: Iec08ab8d9ef7fe7cccde979530839ef553779658
2015-08-02 14:56:44 -07:00
Kunal Mehta
1ebb0f5659 registration: Overhaul merging of globals
Instead of hardcoding specific global settings in ExtensionRegistry,
create specific "merge strategies" that are used to merge globals.

Merge strategies are set for core properties in the ExtensionProcessor,
and extensions can set them for their own configuration settings using
the magic "_merge_strategy" key.

The following merge strategies are included:
* array_merge_recursive - call `array_merge_recursive` on the two arrays
* array_plus - use the "+" operator to combine arrays, preserving
               integer keys
* array_plus_2d - A version of array_plus that works on 2d arrays, used
                  for merging arrays like $wgGroupPermissions
* array_merge - call `array_merge` (default)

This changes the merging of various namespaces related settings to use
array_plus so they actually work.

Bug: T107646
Change-Id: I64cb0553864e3b78b0f203333f58bb73b86a6434
2015-08-02 12:04:25 -07:00
Kunal Mehta
d75391883e registration: Fix merging of $wgRevokePermissions
It's the same as $wgGroupPermissions.

Change-Id: I9c289219c53314970e7af5998c00d6a372bb00cb
2015-07-31 23:40:07 -07:00
Kunal Mehta
648ef0d868 Read extension.json files in the web updater
The web updater reads LocalSettings.php in function scope to figure out
what extensions have been loaded. This doesn't work for extensions being
loaded through the ExtensionRegistry since they're only added to a
queue.

This adds the ability for the installer to read and get information from
the current extension load queue. LocalSettings.php is still read for
extensions that have not been converted yet.

Other uses of Installer::getExistingLocalSettings() were audited and
determined to be safe with regards to extension usage.

Extensions that register hooks using explicit globals
($GLOBALS['wgHooks']['FooBar']) are still broken.

Bug: T100414
Change-Id: Icc574a38a7947a1e3aff8622a4889e9dcfd7a4b2
2015-07-25 22:32:27 +00:00
umherirrender
d8821f2b0b Fixed spacing
- Removed space after casts
- Removed spaces in array index
- Added spaces around string concat
- Added space after words: switch, foreach
- else if -> elseif
- Removed parentheses around require_once, because it is not a function
- Added newline at end of file
- Removed double spaces
- Added spaces around operations
- Removed repeated newlines

Bug: T102609
Change-Id: Ib860222b24f8ad8e9062cd4dc42ec88dc63fb49e
2015-06-17 20:22:32 +00:00
Kunal Mehta
ce5a0c5cd2 registration: Don't override boolean false settings
Our optimization of !$GLOBALS[$key] was affecting settings where a true
setting was being disabled in LocalSettings.php. Now explicitly check it
is an array before overriding it.

Bug: T100767
Change-Id: Id5397e526d66559bfabe6065223b1181a8a9d31e
2015-06-03 08:03:20 -07:00