+# Repository management
.svn
-*~
+
+# Editors
*.kate-swp
+*~
.*.swp
-.classpath
-.idea
-.metadata*
.project
-.settings
-AdminSettings.php
-LocalSettings.php
-StartProfiler.php
cscope.files
cscope.out
-favicon.ico
+## NetBeans
nbproject*
project.index
-static*
-tags
+
+# MediaWiki install & usage
cache/*.cdb
images/[0-9a-f]
images/archive
images/deleted
images/temp
images/thumb
+## Extension:EasyTimeline
images/timeline
images/tmp
-maintenance/dev/data
maintenance/.mweval_history
maintenance/.mwsql_history
+maintenance/dev/data
+AdminSettings.php
+LocalSettings.php
+StartProfiler.php
+
+# Operating systems
+## Mac OS X
+.DS_Store
+
+# Misc
+.classpath
+.idea
+.metadata*
+.settings
+favicon.ico
+static*
+tags
* Added support in jquery.localize for placeholder attributes.
* (bug 38151) Implemented mw.user.getRights for getting and caching the current
user's user rights.
+* Session storage can now configured independently of general object cache
+ storage, by using $wgSessionCacheType. $wgSessionsInMemcached has been
+ renamed to $wgSessionsInObjectCache, with the old name retained for backwards
+ compatibility.
* Implemented mw.user.getGroups for getting and caching user groups.
* (bug 37830) Added $wgRequirePasswordforEmailChange to control whether password
confirmation is required for changing an email address or not.
'MultiWriteBagOStuff' => 'includes/objectcache/MultiWriteBagOStuff.php',
'MWMemcached' => 'includes/objectcache/MemcachedClient.php',
'ObjectCache' => 'includes/objectcache/ObjectCache.php',
+ 'ObjectCacheSessionHandler' => 'includes/objectcache/ObjectCacheSessionHandler.php',
'SqlBagOStuff' => 'includes/objectcache/SqlBagOStuff.php',
'WinCacheBagOStuff' => 'includes/objectcache/WinCacheBagOStuff.php',
'XCacheBagOStuff' => 'includes/objectcache/XCacheBagOStuff.php',
*/
$wgParserCacheType = CACHE_ANYTHING;
+/**
+ * The cache type for storing session data. Used if $wgSessionsInObjectCache is true.
+ *
+ * For available types see $wgMainCacheType.
+ */
+$wgSessionCacheType = CACHE_ANYTHING;
+
/**
* The cache type for storing language conversion tables,
* which are used when parsing certain text and interface messages.
$wgDBAhandler = 'db3';
/**
- * Store sessions in MemCached. This can be useful to improve performance, or to
- * avoid the locking behaviour of PHP's default session handler, which tends to
- * prevent multiple requests for the same user from acting concurrently.
+ * Deprecated alias for $wgSessionsInObjectCache.
+ *
+ * @deprecated Use $wgSessionsInObjectCache
*/
$wgSessionsInMemcached = false;
+/**
+ * Store sessions in an object cache, configured by $wgSessionCacheType. This
+ * can be useful to improve performance, or to avoid the locking behaviour of
+ * PHP's default session handler, which tends to prevent multiple requests for
+ * the same user from acting concurrently.
+ */
+$wgSessionsInObjectCache = false;
+
/**
* This is used for setting php's session.save_handler. In practice, you will
* almost never need to change this ever. Other options might be 'user' or
* @param $sessionId Bool
*/
function wfSetupSession( $sessionId = false ) {
- global $wgSessionsInMemcached, $wgCookiePath, $wgCookieDomain,
+ global $wgSessionsInMemcached, $wgSessionsInObjectCache, $wgCookiePath, $wgCookieDomain,
$wgCookieSecure, $wgCookieHttpOnly, $wgSessionHandler;
- if( $wgSessionsInMemcached ) {
- if ( !defined( 'MW_COMPILED' ) ) {
- global $IP;
- require_once( "$IP/includes/cache/MemcachedSessions.php" );
- }
- session_set_save_handler( 'memsess_open', 'memsess_close', 'memsess_read',
- 'memsess_write', 'memsess_destroy', 'memsess_gc' );
-
- // It's necessary to register a shutdown function to call session_write_close(),
- // because by the time the request shutdown function for the session module is
- // called, $wgMemc has already been destroyed. Shutdown functions registered
- // this way are called before object destruction.
- register_shutdown_function( 'memsess_write_close' );
+ if( $wgSessionsInObjectCache || $wgSessionsInMemcached ) {
+ ObjectCacheSessionHandler::install();
} elseif( $wgSessionHandler && $wgSessionHandler != ini_get( 'session.save_handler' ) ) {
# Only set this if $wgSessionHandler isn't null and session.save_handler
# hasn't already been set to the desired value (that causes errors)
if ( wfRunHooks( 'AbortEmailNotification', array($editor, $title) ) ) {
# @todo FIXME: This would be better as an extension hook
$enotif = new EmailNotification();
- $status = $enotif->notifyOnPageChange( $editor, $title,
+ $enotif->notifyOnPageChange( $editor, $title,
$this->mAttribs['rc_timestamp'],
$this->mAttribs['rc_comment'],
$this->mAttribs['rc_minor'],
if ( !$oldfile->exists() || !$oldfile->isLocal() || $oldfile->getRedirected() ) {
return array( array( 'nodeleteablefile' ) );
}
- } else {
- $oldfile = false;
}
if ( is_null( $reason ) ) { // Log and RC don't like null reasons
$args = array_merge( array( $params, 'entirewatchlist' ), array_keys( $pageSet->getAllowedParams() ) );
call_user_func_array( array( $this, 'requireOnlyOneParameter' ), $args );
- $db = $this->getDB();
$dbw = $this->getDB( DB_MASTER );
$timestamp = null;
}
// Now, put the valid titles into the result
- $pages = array();
foreach ( $pageSet->getTitles() as $title ) {
$ns = $title->getNamespace();
$dbkey = $title->getDBkey();
* @return array
*/
protected function getApiWarnings() {
- $warnings = array();
-
$warnings = $this->mUpload->checkWarnings();
return $this->transformWarnings( $warnings );
+++ /dev/null
-<?php
-/**
- * Session storage in object cache.
- *
- * This file gets included if $wgSessionsInMemcache is set in the config.
- * It redirects session handling functions to store their data in memcached
- * instead of the local filesystem. Depending on circumstances, it may also
- * be necessary to change the cookie settings to work across hostnames.
- * See: http://www.php.net/manual/en/function.session-set-save-handler.php
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Cache
- */
-
-/**
- * Get a cache key for the given session id.
- *
- * @param $id String: session id
- * @return String: cache key
- */
-function memsess_key( $id ) {
- return wfMemcKey( 'session', $id );
-}
-
-/**
- * Callback when opening a session.
- * NOP: $wgMemc should be set up already.
- *
- * @param $save_path String: path used to store session files, unused
- * @param $session_name String: session name
- * @return Boolean: success
- */
-function memsess_open( $save_path, $session_name ) {
- return true;
-}
-
-/**
- * Callback when closing a session.
- * NOP.
- *
- * @return Boolean: success
- */
-function memsess_close() {
- return true;
-}
-
-/**
- * Callback when reading session data.
- *
- * @param $id String: session id
- * @return Mixed: session data
- */
-function memsess_read( $id ) {
- global $wgMemc;
- $data = $wgMemc->get( memsess_key( $id ) );
- if( ! $data ) return '';
- return $data;
-}
-
-/**
- * Callback when writing session data.
- *
- * @param $id String: session id
- * @param $data Mixed: session data
- * @return Boolean: success
- */
-function memsess_write( $id, $data ) {
- global $wgMemc;
- $wgMemc->set( memsess_key( $id ), $data, 3600 );
- return true;
-}
-
-/**
- * Callback to destroy a session when calling session_destroy().
- *
- * @param $id String: session id
- * @return Boolean: success
- */
-function memsess_destroy( $id ) {
- global $wgMemc;
-
- $wgMemc->delete( memsess_key( $id ) );
- return true;
-}
-
-/**
- * Callback to execute garbage collection.
- * NOP: Memcached performs garbage collection.
- *
- * @param $maxlifetime Integer: maximum session life time
- * @return Boolean: success
- */
-function memsess_gc( $maxlifetime ) {
- return true;
-}
-
-function memsess_write_close() {
- session_write_close();
-}
-
* Make sure remaining locks get cleared for sanity
*/
function __destruct() {
- foreach ( $this->conns as $lockDb => $db ) {
+ foreach ( $this->conns as $db ) {
if ( $db->trxLevel() ) { // in transaction
try {
$db->rollback( __METHOD__ ); // finish transaction and kill any rows
public function getIRCActionText() {
$this->plaintext = true;
$this->irctext = true;
- $text = $this->getActionText();
$entry = $this->entry;
$parameters = $entry->getParameters();
--- /dev/null
+<?php
+/*
+ * Session storage in object cache.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ */
+class ObjectCacheSessionHandler {
+ /**
+ * Install a session handler for the current web request
+ */
+ static function install() {
+ session_set_save_handler(
+ array( __CLASS__, 'open' ),
+ array( __CLASS__, 'close' ),
+ array( __CLASS__, 'read' ),
+ array( __CLASS__, 'write' ),
+ array( __CLASS__, 'destroy' ),
+ array( __CLASS__, 'gc' ) );
+
+ // It's necessary to register a shutdown function to call session_write_close(),
+ // because by the time the request shutdown function for the session module is
+ // called, $wgMemc has already been destroyed. Shutdown functions registered
+ // this way are called before object destruction.
+ register_shutdown_function( array( __CLASS__, 'handleShutdown' ) );
+ }
+
+ /**
+ * Get the cache storage object to use for session storage
+ */
+ static function getCache() {
+ global $wgSessionCacheType;
+ return ObjectCache::getInstance( $wgSessionCacheType );
+ }
+
+ /**
+ * Get a cache key for the given session id.
+ *
+ * @param $id String: session id
+ * @return String: cache key
+ */
+ static function getKey( $id ) {
+ return wfMemcKey( 'session', $id );
+ }
+
+ /**
+ * Callback when opening a session.
+ *
+ * @param $save_path String: path used to store session files, unused
+ * @param $session_name String: session name
+ * @return Boolean: success
+ */
+ static function open( $save_path, $session_name ) {
+ return true;
+ }
+
+ /**
+ * Callback when closing a session.
+ * NOP.
+ *
+ * @return Boolean: success
+ */
+ static function close() {
+ return true;
+ }
+
+ /**
+ * Callback when reading session data.
+ *
+ * @param $id String: session id
+ * @return Mixed: session data
+ */
+ static function read( $id ) {
+ $data = self::getCache()->get( self::getKey( $id ) );
+ if( $data === false ) {
+ return '';
+ }
+ return $data;
+ }
+
+ /**
+ * Callback when writing session data.
+ *
+ * @param $id String: session id
+ * @param $data Mixed: session data
+ * @return Boolean: success
+ */
+ static function write( $id, $data ) {
+ self::getCache()->set( self::getKey( $id ), $data, 3600 );
+ return true;
+ }
+
+ /**
+ * Callback to destroy a session when calling session_destroy().
+ *
+ * @param $id String: session id
+ * @return Boolean: success
+ */
+ static function destroy( $id ) {
+ self::getCache()->delete( self::getKey( $id ) );
+ return true;
+ }
+
+ /**
+ * Callback to execute garbage collection.
+ * NOP: Object caches perform garbage collection implicitly
+ *
+ * @param $maxlifetime Integer: maximum session life time
+ * @return Boolean: success
+ */
+ static function gc( $maxlifetime ) {
+ return true;
+ }
+
+ /**
+ * Shutdown function. See the comment inside ObjectCacheSessionHandler::install
+ * for rationale.
+ */
+ static function handleShutdown() {
+ session_write_close();
+ }
+}
// or {{filepath|300px}}, {{filepath|200x300px}}, {{filepath|nowiki|200x300px}}, {{filepath|200x300px|nowiki}}
public static function filepath( $parser, $name='', $argA='', $argB='' ) {
$file = wfFindFile( $name );
- $isNowiki = false;
if( $argA == 'nowiki' ) {
// {{filepath: | option [| size] }}
if ( count( $fields ) > 1 && $count > 30 ) {
$this->toc = Linker::tocIndent();
$tocLength = 0;
- foreach( $fields as $key => $data ) {
+ foreach( $fields as $data ) {
# strip out the 'ns' prefix from the section name:
$ns = substr( $data['section'], 2 );
$query = array( 'wpCookieCheck' => $type );
if ( $this->mReturnTo ) {
$query['returnto'] = $this->mReturnTo;
+ $query['returntoquery'] = $this->mReturnToQuery;
}
$check = $titleObj->getFullURL( $query );
// Output a copy of this first to chunk 0 location:
$status = $this->outputChunk( $this->mLocalFile->getPath() );
-
+
// Update db table to reflect initial "chunk" state
$this->updateChunkStatus();
return $this->mLocalFile;
$this->mUpload = $webRequestUpload;
// Get the chunk status form the db:
$this->getChunkStatus();
-
+
$metadata = $this->stash->getMetadata( $key );
$this->initializePathInfo( $name,
$this->getRealPath( $metadata['us_path'] ),
false
);
}
-
+
/**
* Append the final chunk and ready file for parent::performUpload()
* @return FileRepoStatus
}
return $status;
}
-
+
/**
* Update the chunk db table with the current status:
*/
__METHOD__
);
}
+
/**
* Get the chunk db state and populate update relevant local values
*/
$this->mVirtualTempPath = $row->us_path;
}
}
+
/**
* Get the current Chunk index
* @return Integer index of the current chunk
}
return 0;
}
-
+
/**
* Gets the current offset in fromt the stashedupload table
* @return Integer current byte offset of the chunk file set
}
return 0;
}
-
+
/**
* Output the chunk to disk
*
* Implementation for mediaWiki.user
*/
-(function( $ ) {
+( function ( $ ) {
/**
* User object
/* Private Members */
var that = this;
- var api = new mw.Api();
- var groupsDeferred;
- var rightsDeferred;
+ var callbacks = {};
+
+ /**
+ * Gets the current user's groups or rights.
+ * @param {String} info: One of 'groups' or 'rights'.
+ * @param {Function} callback
+ */
+ function getUserInfo( info, callback ) {
+ var api;
+ if ( callbacks[info] ) {
+ callbacks[info].add( callback );
+ return;
+ }
+ callbacks.rights = $.Callbacks('once memory');
+ callbacks.groups = $.Callbacks('once memory');
+ callbacks[info].add( callback );
+ api = new mw.Api();
+ api.get( {
+ action: 'query',
+ meta: 'userinfo',
+ uiprop: 'rights|groups'
+ } ).always( function ( data ) {
+ var rights, groups;
+ if ( data.query && data.query.userinfo ) {
+ rights = data.query.userinfo.rights;
+ groups = data.query.userinfo.groups;
+ }
+ callbacks.rights.fire( rights || [] );
+ callbacks.groups.fire( groups || [] );
+ } );
+ }
/* Public Members */
*/
this.sessionId = function () {
var sessionId = $.cookie( 'mediaWiki.user.sessionId' );
- if ( typeof sessionId == 'undefined' || sessionId === null ) {
+ if ( typeof sessionId === 'undefined' || sessionId === null ) {
sessionId = generateId();
$.cookie( 'mediaWiki.user.sessionId', sessionId, { 'expires': null, 'path': '/' } );
}
return name;
}
var id = $.cookie( 'mediaWiki.user.id' );
- if ( typeof id == 'undefined' || id === null ) {
+ if ( typeof id === 'undefined' || id === null ) {
id = generateId();
}
// Set cookie if not set, or renew it if already set
* Gets the current user's groups.
*/
this.getGroups = function ( callback ) {
- if ( groupsDeferred ) {
- groupsDeferred.always( callback );
- return;
- }
-
- groupsDeferred = $.Deferred();
- groupsDeferred.always( callback );
- api.get( {
- action: 'query',
- meta: 'userinfo',
- uiprop: 'groups'
- } ).done( function ( data ) {
- if ( data.query && data.query.userinfo && data.query.userinfo.groups ) {
- groupsDeferred.resolve( data.query.userinfo.groups );
- } else {
- groupsDeferred.reject( [] );
- }
- } ).fail( function ( data ) {
- groupsDeferred.reject( [] );
- } );
+ getUserInfo( 'groups', callback );
};
/**
* Gets the current user's rights.
*/
this.getRights = function ( callback ) {
- if ( rightsDeferred ) {
- rightsDeferred.always( callback );
- return;
- }
-
- rightsDeferred = $.Deferred();
- rightsDeferred.always( callback );
- api.get( {
- action: 'query',
- meta: 'userinfo',
- uiprop: 'rights'
- } ).done( function ( data ) {
- if ( data.query && data.query.userinfo && data.query.userinfo.rights ) {
- rightsDeferred.resolve( data.query.userinfo.rights );
- } else {
- rightsDeferred.reject( [] );
- }
- } ).fail( function ( data ) {
- rightsDeferred.reject( [] );
- } );
+ getUserInfo( 'rights', callback );
};
}
// This is kind of ugly but we're stuck with this for b/c reasons
mw.user = new User( mw.user.options, mw.user.tokens );
-})(jQuery);
+}( jQuery ) );