r48343 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r48342‎ | r48343 | r48344 >
Date:11:01, 12 March 2009
Author:ialex
Status:deferred
Tags:
Comment:
(bug 17112) Added dependencies checking for extensions

For now, just added AntiSpoof dependency for AbuseFilter and $wgEnableEmail = true for ConfirmAccount
Modified paths:
  • /trunk/extensions/Configure/CHANGELOG (modified) (history)
  • /trunk/extensions/Configure/Configure.ext.php (modified) (history)
  • /trunk/extensions/Configure/Configure.i18n.php (modified) (history)
  • /trunk/extensions/Configure/Configure.page.php (modified) (history)
  • /trunk/extensions/Configure/Configure.php (modified) (history)
  • /trunk/extensions/Configure/Configure.settings-ext.txt (modified) (history)
  • /trunk/extensions/Configure/Configure.settings.php (modified) (history)
  • /trunk/extensions/Configure/SpecialExtensions.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Configure/Configure.page.php
@@ -108,7 +108,7 @@
109109 $this->showForm();
110110 break;
111111 case 'diff':
112 - $this->conf = $this->importFromRequest();
 112+ $this->conf = $this->importFromRequest() + $this->conf;
113113 $this->showDiff();
114114 case 'initial':
115115 default:
@@ -164,6 +164,15 @@
165165 }
166166
167167 /**
 168+ * Accessor for $this->conf
 169+ *
 170+ * @return array
 171+ */
 172+ public function getConf() {
 173+ return $this->conf;
 174+ }
 175+
 176+ /**
168177 * Return true if the current user is allowed to configure $setting.
169178 * @return bool
170179 */
Index: trunk/extensions/Configure/CHANGELOG
@@ -1,6 +1,9 @@
22 This file lists changes on this extension.
33 Localisation updates are done on betawiki and aren't listed here.
44
 5+0.13.1 - 12 March 2009
 6+ (bug 17112) Added dependencies checking for extensions.
 7+
58 0.13.0 - 11 March 2009
69 Rewrote extension definitions handling, now using text file.
710
Index: trunk/extensions/Configure/Configure.settings-ext.txt
@@ -15,6 +15,7 @@
1616 settings[] = wgAbuseFilterRestrictedActions: array
1717 array[] = wgAbuseFilterAvailableActions: simple
1818 array[] = wgAbuseFilterRestrictedActions: simple
 19+extensions-dependencies[] = AntiSpoof
1920 schema = true
2021 url = http://www.mediawiki.org/wiki/Extension:AbuseFilter
2122
@@ -240,6 +241,7 @@
241242 settings[] = wgAccountRequestExts: array
242243 array[] = wgAccountRequestTypes: array, wgConfirmAccountSortkey: simple
243244 array[] = wgAccountRequestExts: simple
 245+settings-dependencies[] = wgEnableEmail: true
244246 schema = true
245247 url = http://www.mediawiki.org/wiki/Extension:ConfirmAccount
246248
Index: trunk/extensions/Configure/Configure.settings.php
@@ -12,6 +12,8 @@
1313 protected $settings, $arrayDefs, $emptyValues, $editRestricted,
1414 $viewRestricted, $notEditableSettings, $settingsVersion;
1515
 16+ protected $extensionsObjects = null;
 17+
1618 // Cache
1719 protected $cache = array();
1820
@@ -51,34 +53,54 @@
5254 wfProfileOut( __METHOD__ );
5355 }
5456
55 - /**
56 - * Get an array of WebExtensions objects
57 - *
58 - * @return array
59 - */
60 - public function getAllExtensionsObjects() {
61 - static $list;
 57+ protected function loadExtensions() {
 58+ if ( is_array( $this->extensionsObjects ) )
 59+ return;
6260
63 - if( isset( $list ) )
64 - return $list;
65 -
6661 wfProfileIn( __METHOD__ );
6762
6863 global $wgConfigureAdditionalExtensions;
6964 $coreExtensions = TxtDef::remapForConfigure( TxtDef::loadFromFile( dirname( __FILE__ ) . '/Configure.settings-ext.txt' ) );
7065 $extensions = array_merge( $coreExtensions, $wgConfigureAdditionalExtensions );
7166 usort( $extensions, array( __CLASS__, 'compExt' ) );
 67+ $list = array();
7268 foreach( $extensions as $ext ) {
7369 $ext = new WebExtension( $ext );
7470 #if( $ext->isInstalled() ) {
7571 $list[] = $ext;
7672 #}
7773 }
 74+
 75+ $this->extensionsObjects = $list;
 76+
7877 wfProfileOut( __METHOD__ );
79 - return $list;
8078 }
8179
8280 /**
 81+ * Get an array of WebExtensions objects
 82+ *
 83+ * @return array
 84+ */
 85+ public function getAllExtensionsObjects() {
 86+ $this->loadExtensions();
 87+
 88+ return $this->extensionsObjects;
 89+ }
 90+
 91+ /**
 92+ * Get an extension object by name
 93+ */
 94+ public function getExtension( $name ) {
 95+ $this->loadExtensions();
 96+
 97+ foreach( $this->extensionsObjects as $ext )
 98+ if ( $ext->getName() == $name )
 99+ return $ext;
 100+
 101+ return null;
 102+ }
 103+
 104+ /**
83105 * Callback to sort extensions
84106 */
85107 public static function compExt( $e1, $e2 ) {
Index: trunk/extensions/Configure/Configure.ext.php
@@ -14,16 +14,19 @@
1515 protected $mEditRestricted;
1616 protected $mName;
1717 protected $mDbChange;
 18+ protected $mExtensionsDependencies;
 19+ protected $mSettingsDependencies;
1820 protected $mInputCallback = null;
1921 protected $mDir;
2022 protected $mFile;
2123 protected $mDoc;
2224 protected $mExtVar = null;
 25+ protected $mObj = null;
2326
2427 /**
2528 * Construct a new object.
2629 *
27 - * @param array $conf
 30+ * @param $conf Array
2831 */
2932 public function __construct( /*array*/ $conf ) {
3033 global $wgConfigureExtensionsVar;
@@ -32,11 +35,13 @@
3336 $this->mSettings = isset( $conf['settings'] ) ? $conf['settings'] : array();
3437 $this->mDbChange = isset( $conf['schema'] ) && $conf['schema'];
3538 $this->mDir = isset( $conf['dir'] ) ? $conf['dir'] : $conf['name'];
36 - $this->mFile = isset( $conf['file'] ) ? $conf['file'] : $conf['name'] . '.php' ;
 39+ $this->mFile = isset( $conf['file'] ) ? $conf['file'] : $conf['name'] . '.php';
3740 $this->mArrays = isset( $conf['array'] ) ? $conf['array'] : array();
3841 $this->mEmptyValues = isset( $conf['empty'] ) ? $conf['empty'] : array();
3942 $this->mViewRestricted = isset( $conf['view-restricted'] ) ? $conf['view-restricted'] : array();
4043 $this->mEditRestricted = isset( $conf['edit-restricted'] ) ? $conf['edit-restricted'] : array();
 44+ $this->mExtensionsDependencies = isset( $conf['extensions-dependencies'] ) ? $conf['extensions-dependencies'] : array();
 45+ $this->mSettingsDependencies = isset( $conf['settings-dependencies'] ) ? $conf['settings-dependencies'] : array();
4146 $this->mDoc = isset( $conf['url'] ) ? $conf['url'] : null;
4247 if ( isset( $wgConfigureExtensionsVar[$this->mName] ) ) {
4348 $this->mExtVar = $wgConfigureExtensionsVar[$this->mName];
@@ -116,6 +121,26 @@
117122 }
118123
119124 /**
 125+ * Get the list of extensions that needs to be activated so that this
 126+ * extension can work
 127+ *
 128+ * @return array
 129+ */
 130+ public function getExtensionsDependencies() {
 131+ return $this->mExtensionsDependencies;
 132+ }
 133+
 134+ /**
 135+ * Get the associative array mapping settings to their values needed by this
 136+ * extension
 137+ *
 138+ * @return array
 139+ */
 140+ public function getSettingsDependencies() {
 141+ return $this->mSettingsDependencies;
 142+ }
 143+
 144+ /**
120145 * Get a url for the description of this extension (or null)
121146 *
122147 * @return string or null
@@ -135,18 +160,47 @@
136161 }
137162
138163 /**
 164+ * Prettify boolean settings to be correctly displayed
 165+ *
 166+ * @return String
 167+ */
 168+ public static function prettifyForDisplay( $val ) {
 169+ if ( is_bool( $val ) )
 170+ return wfBoolToStr( $val );
 171+ return $val;
 172+ }
 173+
 174+ /**
139175 * Generate html to configure this extension
140176 *
141 - * @return XHTML
 177+ * @return String: XHTML
142178 */
143179 public function getHtml() {
144180 if ( !$this->isInstalled() )
145181 return '';
146182 $ret = '<fieldset><legend>' . htmlspecialchars( $this->mName ) . '</legend>';
 183+ if ( count( $errors = $this->checkSettingsDependencies() ) ) {
 184+ $ret .= "<span class=\"errorbox\">";
 185+ $ret .= wfMsgExt( 'configure-ext-settings-dep-errors', array( 'parseinline' ), count( $errors ) );
 186+ $ret .= "<ul>\n";
 187+ foreach ( $errors as $err ) {
 188+ list( $setting, $req, $cur ) = $err;
 189+ $setting = '$'.$setting;
 190+ $req = self::prettifyForDisplay( $req );
 191+ $cur = self::prettifyForDisplay( $cur );
 192+ $ret .= '<li>' . wfMsgExt( 'configure-ext-settings-dep-error', array( 'parseinline' ), $setting, $req, $cur ) . "</li>\n";
 193+ }
 194+ return $ret . "</ul>\n</span>\n</fieldset>";
 195+ }
147196 if ( $this->mDbChange ) {
148197 $warn = wfMsgExt( 'configure-ext-schemachange', array( 'parseinline' ) );
149198 $ret .= "<span class=\"errorbox\">{$warn}</span><br clear=\"left\" />\n";
150199 }
 200+ if ( count( $this->mExtensionsDependencies ) ) {
 201+ global $wgLang;
 202+ $warn = wfMsgExt( 'configure-ext-ext-dependencies', array( 'parseinline' ), $wgLang->listToText( $this->mExtensionsDependencies ), count( $this->mExtensionsDependencies ) );
 203+ $ret .= "<span class=\"errorbox\">{$warn}</span><br clear=\"left\" />\n";
 204+ }
151205 $use = wfMsgExt( 'configure-ext-use', array( 'parseinline' ) );
152206 $ret .= "<h2>{$use}</h2>\n";
153207 $ret .= "<table class=\"configure-table configure-table-ext\"><tr><td>\n";
@@ -176,6 +230,39 @@
177231 }
178232
179233 /**
 234+ * Check for settings dependencies
 235+ *
 236+ * @return Boolean: Success
 237+ */
 238+ public function checkSettingsDependencies() {
 239+ if ( !$this->mObj instanceof ConfigurationPage )
 240+ throw new MWException( 'WebExtension::checkSettingsDependencies() called without prior call to WebExtension::setPageObj()' );
 241+
 242+ if ( !count( $this->mSettingsDependencies ) )
 243+ return array();
 244+
 245+ $ret = array();
 246+ $conf = $this->mObj->getConf();
 247+ foreach ( $this->mSettingsDependencies as $setting => $value ) {
 248+ if ( $conf[$setting] !== $value ) {
 249+ $ret[] = array( $setting, $value, $conf[$setting] );
 250+ }
 251+ }
 252+ return $ret;
 253+ }
 254+
 255+ /**
 256+ * Whether the definition file can be included to get default values
 257+ *
 258+ * @return Boolean
 259+ */
 260+ public function canIncludeFile() {
 261+ if( !file_exists( $this->getFile() ) )
 262+ return false;
 263+ return !count( $this->checkSettingsDependencies() );
 264+ }
 265+
 266+ /**
180267 * Return the name of the check that's used to select whether the extension
181268 * should be activated
182269 */
@@ -203,7 +290,7 @@
204291 /**
205292 * Is this extension activated?
206293 *
207 - * @return bool
 294+ * @return Boolean
208295 */
209296 public function isActivated() {
210297 if( $this->useVariable() ) {
@@ -217,7 +304,7 @@
218305 /**
219306 * Is this extension installed so that it can be used?
220307 *
221 - * @return bool
 308+ * @return Boolean
222309 */
223310 public function isInstalled() {
224311 if( $this->useVariable() ) {
Index: trunk/extensions/Configure/Configure.php
@@ -17,7 +17,7 @@
1818 'url' => 'http://www.mediawiki.org/wiki/Extension:Configure',
1919 'description' => 'Allow authorised users to configure the wiki via a web-based interface',
2020 'descriptionmsg' => 'configure-desc',
21 - 'version' => '0.13.0',
 21+ 'version' => '0.13.1',
2222 );
2323
2424 # Configuration part
@@ -88,6 +88,10 @@
8989 * extensions-all right
9090 * - edit-restricted: list of settings that only be modified by users with
9191 * extensions-all right
 92+ * - extensions-dependencies: list of extensions that must be enabled so that
 93+ * this extension can be enabled too
 94+ * - settings-dependencies: array mapping settings to their values that must be
 95+ * set so that this extension can be enabled
9296 * - schema: put it to true if the extension requires a database schema change
9397 * - url: url to the documentation page
9498 */
Index: trunk/extensions/Configure/Configure.i18n.php
@@ -20,9 +20,13 @@
2121 'configure-edit-ext' => 'Extensions',
2222 'configure-viewconfig-default-diff' => 'Changes from default settings',
2323
 24+ 'configure-ext-ext-dependencies' => "'''Warning:''' this extension requires the following {{PLURAL:$2|extension|extensions}} to be activated: $1.",
 25+ 'configure-ext-ext-dependency-err' => "'''Error:''' the $1 extension requires the $2 extension to be activated.",
2426 'configure-ext-doc' => 'See online documentation',
2527 'configure-ext-schemachange' => "'''Warning:''' this extension requires a database update to work correctly!",
2628 'configure-ext-settings' => 'Settings',
 29+ 'configure-ext-settings-dep-errors' => 'This extension cannot be enabled because the following {{PLURAL:$1|setting has|settings have}} an unacceptable value:',
 30+ 'configure-ext-settings-dep-error' => '$1: required value: $2, current value: $3',
2731 'configure-ext-use-extension' => 'Use this extension',
2832 'configure-ext-use' => 'Use',
2933 'configure-form-reason' => 'Reason for change:',
Index: trunk/extensions/Configure/SpecialExtensions.php
@@ -28,6 +28,11 @@
2929 $current = $wgConf->getCurrent( $this->mWiki );
3030 $settings = $this->importFromRequest();
3131 $new = $settings + $current;
 32+ if ( !$this->checkExtensionsDependencies() ) {
 33+ $this->conf = $new;
 34+ $this->showForm();
 35+ return;
 36+ }
3237 $new = $this->removeDefaults( $new );
3338 $new['__includes'] = $this->getRequiredFiles();
3439 $ok = $wgConf->saveNewSettings( $new, $this->mWiki, $reason );
@@ -52,6 +57,31 @@
5358 }
5459
5560 /**
 61+ * Check dependencies against other extensions, and print errors if any
 62+ *
 63+ * @return Boolean: success
 64+ */
 65+ protected function checkExtensionsDependencies() {
 66+ global $wgRequest, $wgOut;
 67+
 68+ foreach ( $this->mConfSettings->getAllExtensionsObjects() as $ext ) {
 69+ if ( !count( $ext->getExtensionsDependencies() ) || !$wgRequest->getCheck( $ext->getCheckName() ) )
 70+ continue;
 71+
 72+ foreach ( $ext->getExtensionsDependencies() as $depName ) {
 73+ $dep = $this->mConfSettings->getExtension( $depName );
 74+ if ( !is_object( $dep ) )
 75+ throw new MWException( "Unable to find \"{$depName}\" dependency for \"{$ext->getName()}\" extension" );
 76+ if ( !$wgRequest->getCheck( $dep->getCheckName() ) ) {
 77+ $wgOut->wrapWikiMsg( '<span class="errorbox">$1</span>', array( 'configure-ext-ext-dependency-err', $ext->getName(), $depName ) );
 78+ return false;
 79+ }
 80+ }
 81+ }
 82+ return true;
 83+ }
 84+
 85+ /**
5686 * Get an array of files to include at each request
5787 * @return array
5888 */
@@ -61,7 +91,8 @@
6292 return array();
6393 $arr = array();
6494 foreach ( $this->mConfSettings->getAllExtensionsObjects() as $ext ) {
65 - if( !$ext->isInstalled() ) continue; // must exist
 95+ if( !$ext->isInstalled() )
 96+ continue; // must exist
6697 if ( $ext->useVariable() )
6798 continue;
6899 if ( $wgRequest->getCheck( $ext->getCheckName() ) )
@@ -93,10 +124,12 @@
94125 $ret = '';
95126 $globalDone = false;
96127 foreach ( $this->mConfSettings->getAllExtensionsObjects() as $ext ) {
97 - if( !$ext->isInstalled() ) continue; // must exist
 128+ if( !$ext->isInstalled() )
 129+ continue; // must exist
 130+ $ext->setPageObj( $this );
98131 $settings = $ext->getSettings();
99132 foreach ( $settings as $setting => $type ) {
100 - if ( !isset( $this->conf[$setting] ) && file_exists( $ext->getFile() ) ) {
 133+ if ( !isset( $this->conf[$setting] ) && $ext->canIncludeFile() ) {
101134 if ( !$globalDone ) {
102135 extract( $GLOBALS, EXTR_REFS );
103136 global $wgHooks;
@@ -109,7 +142,6 @@
110143 $this->conf[$setting] = $$setting;
111144 }
112145 }
113 - $ext->setPageObj( $this );
114146 $ret .= $ext->getHtml();
115147 }
116148 if ( $globalDone )

Status & tagging log