'CompareParserCache' => __DIR__ . '/maintenance/compareParserCache.php',
'CompareParsers' => __DIR__ . '/maintenance/compareParsers.php',
'ComposerHookHandler' => __DIR__ . '/includes/composer/ComposerHookHandler.php',
+ 'ComposerInstalled' => __DIR__ . '/includes/libs/composer/ComposerInstalled.php',
'ComposerJson' => __DIR__ . '/includes/libs/composer/ComposerJson.php',
'ComposerLock' => __DIR__ . '/includes/libs/composer/ComposerLock.php',
'ComposerPackageModifier' => __DIR__ . '/includes/composer/ComposerPackageModifier.php',
if ( $target->getText() == '' && !$target->isExternal()
&& !$local && $title
) {
- $newTarget = clone ( $title );
+ $newTarget = clone $title;
$newTarget->setFragment( '#' . $target->getFragment() );
$target = $newTarget;
}
public $mName;
/** @var string */
public $mRealName;
-
- /**
- * These fields were marked "@private", but were defined as public to
- * maintain compatibility with PHP4 code since PHP4 didn't support access
- * restrictions. AuthManager makes password handling pluggable, meaning
- * these fields don't make sense anymore. If this broke something, see
- * T89459 for the context of the change.
- * @deprecated These are mostly unused, but kept for now to raise errors on attempted access.
- */
- // @{
+ /** @var Password|null */
private $mPassword = null;
- private $mNewpassword;
- private $mNewpassTime;
- private $mPasswordExpires;
- // @}
/** @var string */
public $mEmail;
__METHOD__
);
try {
- $mNewpassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
+ $newPassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
} catch ( PasswordError $e ) {
wfDebug( 'Invalid password hash found in database.' );
- $mNewpassword = PasswordFactory::newInvalidPassword();
+ $newPassword = PasswordFactory::newInvalidPassword();
}
- if ( $mNewpassword->equals( $plaintext ) ) {
+ if ( $newPassword->equals( $plaintext ) ) {
if ( is_null( $row->user_newpass_time ) ) {
return true;
}
protected function appendInstalledLibraries( $property ) {
global $IP;
- $path = "$IP/composer.lock";
+ $path = "$IP/vendor/composer/installed.json";
if ( !file_exists( $path ) ) {
- // Maybe they're using mediawiki/vendor?
- $path = "$IP/vendor/composer.lock";
- if ( !file_exists( $path ) ) {
- return true;
- }
+ return true;
}
$data = array();
- $lock = new ComposerLock( $path );
- foreach ( $lock->getInstalledDependencies() as $name => $info ) {
+ $installed = new ComposerInstalled( $path );
+ foreach ( $installed->getInstalledDependencies() as $name => $info ) {
if ( strpos( $info['type'], 'mediawiki-' ) === 0 ) {
// Skip any extensions or skins since they'll be listed
// in their proper section
// passing to the parent constructor. Our overridden report() below
// makes sure that the page shown to the user is not forced to English.
if ( $msg instanceof Message ) {
- $enMsg = clone( $msg );
+ $enMsg = clone $msg;
} else {
$enMsg = wfMessage( $msg, $params );
}
'wgRightsIcon',
'wgRightsText',
'wgRightsUrl',
- 'wgMainCacheType',
'wgEnableEmail',
'wgEnableUserEmail',
'wgEnotifUserTalk',
'wgLanguageCode', 'wgEnableEmail', 'wgEnableUserEmail', 'wgDiff3',
'wgEnotifUserTalk', 'wgEnotifWatchlist', 'wgEmailAuthentication',
'wgDBtype', 'wgSecretKey', 'wgRightsUrl', 'wgSitename', 'wgRightsIcon',
- 'wgRightsText', 'wgMainCacheType', 'wgEnableUploads',
- 'wgMainCacheType', '_MemCachedServers', 'wgDBserver', 'wgDBuser',
+ 'wgRightsText', '_MainCacheType', 'wgEnableUploads',
+ '_MemCachedServers', 'wgDBserver', 'wgDBuser',
'wgDBpassword', 'wgUseInstantCommons', 'wgUpgradeKey', 'wgDefaultSkin',
'wgMetaNamespace', 'wgLogo',
),
$serverSetting .= "\$wgServer = \"{$this->values['wgServer']}\";";
}
- switch ( $this->values['wgMainCacheType'] ) {
+ switch ( $this->values['_MainCacheType'] ) {
case 'anything':
case 'db':
case 'memcached':
case 'accel':
- $cacheType = 'CACHE_' . strtoupper( $this->values['wgMainCacheType'] );
+ $cacheType = 'CACHE_' . strtoupper( $this->values['_MainCacheType'] );
break;
case 'none':
default:
$caches[] = 'memcached';
// We'll hide/show this on demand when the value changes, see config.js.
- $cacheval = $this->getVar( 'wgMainCacheType' );
+ $cacheval = $this->getVar( '_MainCacheType' );
if ( !$cacheval ) {
// We need to set a default here; but don't hardcode it
// or we lose it every time we reload the page for validation
// For grep: The following messages are used as the item labels:
// config-cache-none, config-cache-accel, config-cache-memcached
$this->parent->getRadioSet( array(
- 'var' => 'wgMainCacheType',
+ 'var' => '_MainCacheType',
'label' => 'config-cache-options',
'itemLabelPrefix' => 'config-cache-',
'values' => $caches,
$this->parent->setVarsFromRequest( array( '_RightsProfile', '_LicenseCode',
'wgEnableEmail', 'wgPasswordSender', 'wgEnableUploads', 'wgLogo',
'wgEnableUserEmail', 'wgEnotifUserTalk', 'wgEnotifWatchlist',
- 'wgEmailAuthentication', 'wgMainCacheType', '_MemCachedServers',
+ 'wgEmailAuthentication', '_MainCacheType', '_MemCachedServers',
'wgUseInstantCommons', 'wgDefaultSkin' ) );
$retVal = true;
}
$this->parent->setVar( '_Extensions', $extsToInstall );
- if ( $this->getVar( 'wgMainCacheType' ) == 'memcached' ) {
+ if ( $this->getVar( '_MainCacheType' ) == 'memcached' ) {
$memcServers = explode( "\n", $this->getVar( '_MemCachedServers' ) );
if ( !$memcServers ) {
$this->parent->showError( 'config-memcache-needservers' );
--- /dev/null
+<?php
+
+/**
+ * Reads an installed.json file and provides accessors to get what is
+ * installed
+ *
+ * @since 1.27
+ */
+class ComposerInstalled {
+
+ /**
+ * @param string $location
+ */
+ public function __construct( $location ) {
+ $this->contents = json_decode( file_get_contents( $location ), true );
+ }
+
+ /**
+ * Dependencies currently installed according to installed.json
+ *
+ * @return array
+ */
+ public function getInstalledDependencies() {
+ $deps = array();
+ foreach ( $this->contents as $installed ) {
+ $deps[$installed['name']] = array(
+ 'version' => ComposerJson::normalizeVersion( $installed['version'] ),
+ 'type' => $installed['type'],
+ 'licenses' => isset( $installed['license'] ) ? $installed['license'] : array(),
+ 'authors' => isset( $installed['authors'] ) ? $installed['authors'] : array(),
+ 'description' => isset( $installed['description'] ) ? $installed['description']: '',
+ );
+ }
+
+ ksort( $deps );
+ return $deps;
+ }
+}
* Retrieve the version of the installed ImageMagick
* You can use PHPs version_compare() to use this value
* Value is cached for one hour.
- * @return string Representing the IM version.
+ * @return string|bool Representing the IM version; false on error
*/
protected function getMagickVersion() {
- global $wgMemc;
-
- $cache = $wgMemc->get( "imagemagick-version" );
- if ( !$cache ) {
- global $wgImageMagickConvertCommand;
- $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand ) . ' -version';
- wfDebug( __METHOD__ . ": Running convert -version\n" );
- $retval = '';
- $return = wfShellExec( $cmd, $retval );
- $x = preg_match( '/Version: ImageMagick ([0-9]*\.[0-9]*\.[0-9]*)/', $return, $matches );
- if ( $x != 1 ) {
- wfDebug( __METHOD__ . ": ImageMagick version check failed\n" );
-
- return null;
+ return ObjectCache::newAccelerator( CACHE_NONE )->getWithSetCallback(
+ "imagemagick-version",
+ 3600,
+ function () {
+ global $wgImageMagickConvertCommand;
+
+ $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand ) . ' -version';
+ wfDebug( __METHOD__ . ": Running convert -version\n" );
+ $retval = '';
+ $return = wfShellExec( $cmd, $retval );
+ $x = preg_match(
+ '/Version: ImageMagick ([0-9]*\.[0-9]*\.[0-9]*)/', $return, $matches
+ );
+ if ( $x != 1 ) {
+ wfDebug( __METHOD__ . ": ImageMagick version check failed\n" );
+
+ return false;
+ }
+
+ return $matches[1];
}
- $wgMemc->set( "imagemagick-version", $matches[1], 3600 );
-
- return $matches[1];
- }
-
- return $cache;
+ );
}
/**
function __construct( $imagePage ) {
parent::__construct( $imagePage->getContext() );
$this->mImagePage = $imagePage;
- $this->mTitle = clone ( $imagePage->getTitle() );
+ $this->mTitle = clone $imagePage->getTitle();
$this->mTitle->setFragment( '#filehistory' );
$this->mImg = null;
$this->mHist = array();
*/
protected function getExternalLibraries() {
global $IP;
- $path = "$IP/composer.lock";
+ $path = "$IP/vendor/composer/installed.json";
if ( !file_exists( $path ) ) {
- // Maybe they're using mediawiki/vendor?
- $path = "$IP/vendor/composer.lock";
- if ( !file_exists( $path ) ) {
- return '';
- }
+ return '';
}
- $lock = new ComposerLock( $path );
+ $installed = new ComposerInstalled( $path );
$out = Html::element(
'h2',
array( 'id' => 'mw-version-libraries' ),
. Html::element( 'th', array(), $this->msg( 'version-libraries-authors' )->text() )
. Html::closeElement( 'tr' );
- foreach ( $lock->getInstalledDependencies() as $name => $info ) {
+ foreach ( $installed->getInstalledDependencies() as $name => $info ) {
if ( strpos( $info['type'], 'mediawiki-' ) === 0 ) {
// Skip any extensions or skins since they'll be listed
// in their proper section
class UploadStash {
// Format of the key for files -- has to be suitable as a filename itself (e.g. ab12cd34ef.jpg)
const KEY_FORMAT_REGEX = '/^[\w-\.]+\.\w*$/';
+ const MAX_US_PROPS_SIZE = 65535;
/**
* repository that this uses to store temp files
wfDebug( __METHOD__ . " inserting $stashPath under $key\n" );
$dbw = $this->repo->getMasterDb();
+ $serializedFileProps = serialize( $fileProps );
+ if ( strlen( $serializedFileProps ) > self::MAX_US_PROPS_SIZE ) {
+ // Database is going to truncate this and make the field invalid.
+ // Prioritize important metadata over file handler metadata.
+ // File handler should be prepared to regenerate invalid metadata if needed.
+ $fileProps['metadata'] = false;
+ $serializedFileProps = serialize( $fileProps );
+ }
+
$this->fileMetadata[$key] = array(
'us_id' => $dbw->nextSequenceValue( 'uploadstash_us_id_seq' ),
'us_user' => $this->userId,
'us_key' => $key,
'us_orig_path' => $path,
'us_path' => $stashPath, // virtual URL
- 'us_props' => $dbw->encodeBlob( serialize( $fileProps ) ),
+ 'us_props' => $dbw->encodeBlob( $serializedFileProps ),
'us_size' => $fileProps['size'],
'us_sha1' => $fileProps['sha1'],
'us_mime' => $fileProps['mime'],
$( '#config_wgSitename' ).on( 'keyup change', syncText ).each( syncText );
// Show/Hide memcached servers when needed
- $( 'input[name$="config_wgMainCacheType"]' ).change( function () {
+ $( 'input[name$="config__MainCacheType"]' ).change( function () {
var $memc = $( '#config-memcachewrapper' );
- if ( $( 'input[name$="config_wgMainCacheType"]:checked' ).val() === 'memcached' ) {
+ if ( $( 'input[name$="config__MainCacheType"]:checked' ).val() === 'memcached' ) {
$memc.show( 'slow' );
} else {
$memc.hide( 'slow' );
},
setWarning: function ( warning ) {
- $( '#wpDestFile-warning' ).html( warning );
+ var $warning = $( $.parseHTML( warning ) );
+ mw.hook( 'wikipage.content' ).fire( $warning );
+ $( '#wpDestFile-warning' ).empty().append( $warning );
// Set a value in the form indicating that the warning is acknowledged and
// doesn't need to be redisplayed post-upload
&:focus {
text-decoration: none;
}
+
+ // a-tags behave different to inputs if the line-height attribute is inherited
+ // from another element (e.g. mw-body-content). They appear bigger as input
+ // tags. See Bug T116427. To fix that, apply the correct line-height (used
+ // for inputs) to a-tags, too.
+ line-height: normal;
}
// Button groups
min-height: 3.75em;
padding-left: 4.75em;
- &:not(:last-child) {
+ &:not( :last-child ) {
margin-bottom: 2px;
}
}
&.oo-ui-iconElement {
- >.oo-ui-iconElement-icon {
+ > .oo-ui-iconElement-icon {
display: block;
width: 3.75em;
height: 3.75em;
left: 0;
- background-color: #ccc;
- opacity: 0.4;
- }
-
- > .mw-widget-titleOptionWidget-hasImage {
- border: 0;
- background-size: cover;
- opacity: 0.7;
+ &:not( .mw-widget-titleOptionWidget-hasImage ) {
+ background-color: #ccc;
+ opacity: 0.4;
+ }
+ &.mw-widget-titleOptionWidget-hasImage {
+ border: 0;
+ background-size: cover;
+ opacity: 0.7;
+ }
}
}
- }
- &.oo-ui-optionWidget-highlighted, &.oo-ui-optionWidget-selected {
- &.oo-ui-iconElement > .mw-widget-titleOptionWidget-hasImage {
- opacity: 1;
+ &.oo-ui-optionWidget-highlighted, &.oo-ui-optionWidget-selected {
+ &.oo-ui-iconElement > .mw-widget-titleOptionWidget-hasImage {
+ opacity: 1;
+ }
}
}
}
* @inheritdoc
*/
mw.ForeignStructuredUpload.BookletLayout.prototype.getText = function () {
- this.upload.addDescription( 'en', this.descriptionWidget.getValue() );
+ var language = mw.config.get( 'wgContentLanguage' );
+ this.upload.addDescription( language, this.descriptionWidget.getValue() );
this.upload.setDate( this.dateWidget.getValue() );
this.upload.addCategories( this.categoriesWidget.getItemsData() );
return this.upload.getText();