* @param $recursive Boolean: queue jobs for recursive updates?
*/
function __construct( $title, $parserOutput, $recursive = true ) {
- parent::__construct( );
+ parent::__construct( false ); // no implicit transaction
if ( !( $title instanceof Title ) ) {
throw new MWException( "The calling convention to LinksUpdate::LinksUpdate() has changed. " .
* @param $page WikiPage Page we are updating
*/
function __construct( WikiPage $page ) {
- parent::__construct( );
+ parent::__construct( false ); // no implicit transaction
$this->mPage = $page;
}
protected $mOptions; //!< SELECT options to be used (array)
private $mHasTransaction; //!< bool whether a transaction is open on this object (internal use only!)
+ protected $mUseTransaction; //!< bool whether this update should be wrapped in a transaction
/**
* Constructor
- **/
- public function __construct( ) {
+ *
+ * @param bool $withTransaction whether this update should be wrapped in a transaction (default: true).
+ * A transaction is only started if no transaction is already in progress,
+ * see beginTransaction() for details.
+ **/
+ public function __construct( $withTransaction = true ) {
global $wgAntiLockFlags;
parent::__construct( );
// @todo: get connection only when it's needed? make sure that doesn't break anything, especially transactions!
$this->mDb = wfGetDB( DB_MASTER );
+
+ $this->mWithTransaction = $withTransaction;
$this->mHasTransaction = false;
}
/**
- * Begin a database transaction.
+ * Begin a database transaction, if $withTransaction was given as true in the constructor for this SqlDataUpdate.
*
- * Because nested transactions are not supportred by the Database class, this implementation
- * checkes Database::trxLevel() and only opens a transaction if none is yet active.
+ * Because nested transactions are not supported by the Database class, this implementation
+ * checks Database::trxLevel() and only opens a transaction if none is already active.
*/
public function beginTransaction() {
+ if ( !$this->mWithTransaction ) {
+ return;
+ }
+
// NOTE: nested transactions are not supported, only start a transaction if none is open
if ( $this->mDb->trxLevel() === 0 ) {
$this->mDb->begin( get_class( $this ) . '::beginTransaction' );
public function commitTransaction() {
if ( $this->mHasTransaction ) {
$this->mDb->commit( get_class( $this ) . '::commitTransaction' );
+ $this->mHasTransaction = false;
}
}
public function abortTransaction() {
if ( $this->mHasTransaction ) {
$this->mDb->rollback( get_class( $this ) . '::abortTransaction' );
+ $this->mHasTransaction = false;
}
}
} else {
$status = $this->doCreateInternal( $params );
$this->clearCache( array( $params['dst'] ) );
- $this->deleteFileCache( $params['dst'] ); // persistent cache
+ if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
+ $this->deleteFileCache( $params['dst'] ); // persistent cache
+ }
}
wfProfileOut( __METHOD__ . '-' . $this->name );
wfProfileOut( __METHOD__ );
} else {
$status = $this->doStoreInternal( $params );
$this->clearCache( array( $params['dst'] ) );
- $this->deleteFileCache( $params['dst'] ); // persistent cache
+ if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
+ $this->deleteFileCache( $params['dst'] ); // persistent cache
+ }
}
wfProfileOut( __METHOD__ . '-' . $this->name );
wfProfileOut( __METHOD__ );
wfProfileIn( __METHOD__ . '-' . $this->name );
$status = $this->doCopyInternal( $params );
$this->clearCache( array( $params['dst'] ) );
- $this->deleteFileCache( $params['dst'] ); // persistent cache
+ if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
+ $this->deleteFileCache( $params['dst'] ); // persistent cache
+ }
wfProfileOut( __METHOD__ . '-' . $this->name );
wfProfileOut( __METHOD__ );
return $status;
$status = $this->doMoveInternal( $params );
$this->clearCache( array( $params['src'], $params['dst'] ) );
$this->deleteFileCache( $params['src'] ); // persistent cache
- $this->deleteFileCache( $params['dst'] ); // persistent cache
+ if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
+ $this->deleteFileCache( $params['dst'] ); // persistent cache
+ }
wfProfileOut( __METHOD__ . '-' . $this->name );
wfProfileOut( __METHOD__ );
return $status;
}
/**
- * Set the cached stat info for a file path
+ * Set the cached stat info for a file path.
+ * Negatives (404s) are not cached. By not caching negatives, we can skip cache
+ * salting for the case when a file is created at a path were there was none before.
*
* @param $path string Storage path
* @param $val mixed Information to cache
min-width: 8px;
height: 14px;
border: 1px solid white;
- border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
- box-shadow: 0px 1px 4px #ccc;
+ border-radius: 8px;
-moz-box-shadow: 0px 1px 4px #ccc;
-webkit-box-shadow: 0px 1px 4px #ccc;
+ box-shadow: 0px 1px 4px #ccc;
background-color: #b60a00;
- background-image: linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
background-image: -o-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
background-image: -moz-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #a70802), color-stop(1, #cf0e00));
background-image: -webkit-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
background-image: -ms-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
- background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #a70802), color-stop(1, #cf0e00));
+ background-image: linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
padding: 0 3px;
text-align: center;
}
-// Badger v1.0 by Daniel Raftery
-// http://thrivingkings.com/badger
-// http://twitter.com/ThrivingKings
-// Modified by Ryan Kaldari <rkaldari@wikimedia.org>
+/**
+ * jQuery Badge plugin
+ *
+ * Based on Badger plugin by Daniel Raftery (http://thrivingkings.com/badger).
+ *
+ * @license MIT
+ */
/**
+ * @author Ryan Kaldari <rkaldari@wikimedia.org>, 2012
+ * @author Andrew Garrett <agarrett@wikimedia.org>, 2012
+ * @author Marius Hoch <hoo@online.de>, 2012
+ *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
*
* This program is distributed WITHOUT ANY WARRANTY.
*/
+( function ( $ ) {
-(function( $ ) {
- $.fn.badge = function( badge, options ) {
- var existingBadge = this.find( '.mw-badge' );
- options = $.extend( {}, options );
+ /**
+ * Allows you to put a numeric "badge" on an item on the page.
+ * See mediawiki.org/wiki/ResourceLoader/Default_modules#jQuery.badge
+ *
+ * @param {string|number} badgeCount An explicit number, or "+n"/ "-n"
+ * to modify the existing value. If the new value is equal or lower than 0,
+ * any existing badge will be removed. The badge container will be appended
+ * to the selected element(s).
+ * @param {Object} options Optional parameters specified below
+ * type: 'inline' or 'overlay' (default)
+ * callback: will be called with the number now shown on the badge as a parameter
+ */
+ $.fn.badge = function ( badgeCount, options ) {
+ var $badge,
+ oldBadgeCount,
+ newBadgeCount,
+ $existingBadge = this.find( '.mw-badge' );
- badge = String(badge);
- if ( badge.charAt(0) === '+' ) {
- if ( existingBadge.length > 0 ) {
- oldBadge = existingBadge.text();
- badge = Math.round( Number( oldBadge ) + Number( badge.substr(1) ) );
- } else {
- badge = badge.substr(1);
- }
- } else if ( badge.charAt(0) === '-' ) {
- if ( existingBadge.length > 0 ) {
- oldBadge = existingBadge.text();
- badge = Math.round( Number( oldBadge ) - Number( badge.substr(1) ) );
+ options = $.extend( { type : 'overlay' }, options );
+
+ // If there is no existing badge, this will give an empty string
+ oldBadgeCount = Number( $existingBadge.text() );
+ if ( isNaN( oldBadgeCount ) ) {
+ oldBadgeCount = 0;
+ }
+
+ // If badgeCount is a number, use that as the new badge
+ if ( typeof badgeCount === 'number' ) {
+ newBadgeCount = badgeCount;
+ } else if ( typeof badgeCount === 'string' ) {
+ // If badgeCount is "+x", add x to the old badge
+ if ( badgeCount.charAt(0) === '+' ) {
+ newBadgeCount = oldBadgeCount + Number( badgeCount.substr(1) );
+ // If badgeCount is "-x", subtract x from the old badge
+ } else if ( badgeCount.charAt(0) === '-' ) {
+ newBadgeCount = oldBadgeCount - Number( badgeCount.substr(1) );
+ // If badgeCount can be converted into a number, convert it
+ } else if ( !isNaN( Number( badgeCount ) ) ) {
+ newBadgeCount = Number( badgeCount );
} else {
- badge = 0;
+ newBadgeCount = 0;
}
+ // Other types are not supported, fall back to 0.
+ } else {
+ newBadgeCount = 0;
}
- if ( Number(badge) <= 0 ) {
- // Clear any existing badge
- existingBadge.remove();
+ // Badge count must be a whole number
+ newBadgeCount = Math.round( newBadgeCount );
+
+ if ( newBadgeCount <= 0 ) {
+ // Badges should only exist for values > 0.
+ $existingBadge.remove();
} else {
// Don't add duplicates
- var $badge = existingBadge;
- if ( existingBadge.length > 0 ) {
- this.find( '.mw-badge-content' ).text( badge );
+ if ( $existingBadge.length ) {
+ $badge = $existingBadge;
+ // Insert the new count into the badge
+ this.find( '.mw-badge-content' ).text( newBadgeCount );
} else {
- $badge = $('<div/>')
- .addClass('mw-badge')
- .addClass('mw-badge-overlay')
+ // Contruct a new badge with the count
+ $badge = $( '<div>' )
+ .addClass( 'mw-badge' )
.append(
- $('<span/>')
- .addClass('mw-badge-content')
- .text(badge)
+ $( '<span>' )
+ .addClass( 'mw-badge-content' )
+ .text( newBadgeCount )
);
- this.append($badge);
+ this.append( $badge );
}
- if ( options.type ) {
- if ( options.type == 'inline' ) {
- $badge.removeClass('mw-badge-overlay')
- .addClass('mw-badge-inline');
- } else if ( options.type == 'overlay' ) {
- $badge.removeClass('mw-badge-inline')
- .addClass('mw-badge-overlay');
- }
+ if ( options.type === 'inline' ) {
+ $badge
+ .removeClass( 'mw-badge-overlay' )
+ .addClass( 'mw-badge-inline' );
+ // Default: overlay
+ } else {
+ $badge
+ .removeClass( 'mw-badge-inline' )
+ .addClass( 'mw-badge-overlay' );
+
}
- // If a callback was specified, call it with the badge number
- if ( options.callback ) {
- options.callback( badge );
+ // If a callback was specified, call it with the badge count
+ if ( $.isFunction( options.callback ) ) {
+ options.callback( newBadgeCount );
}
}
};
-} ) ( jQuery );
+}( jQuery ) );