* Refactored FileRepo::initZones() to require the specific zones; nothing was using it differently.
* Removed deleted zone check in deleteBatch(), a similar error will instead trigger with the initZones() call as needed.
* Added $wgLocalFileRepo comment.
* Updated tests.
* FSRepo is also supported for backwards compatibility.
*
* - name A unique name for the repository (but $wgLocalFileRepo should be 'local').
+ * - backend A file backend name (see $wgFileBackends).
*
* For most core repos:
* - url Base public URL
);
}
/*
- * Add on default file backend config for repos to $wgFileBackends
+ * Add on default file backend config for file repos.
+ * FileBackendGroup will handle initializing the backends.
*/
if ( !isset( $wgLocalFileRepo['backend'] ) ) {
- $wgFileBackends[] = wfBackendForLegacyRepoConf( $wgLocalFileRepo );
+ $wgLocalFileRepo['backend'] = $wgLocalFileRepo['name'] . '-backend';
}
foreach ( $wgForeignFileRepos as &$repo ) {
+ if ( !isset( $repo['directory'] ) && $repo['class'] === 'ForeignAPIRepo' ) {
+ $repo['directory'] = $wgUploadDirectory; // b/c
+ }
if ( !isset( $repo['backend'] ) ) {
- $wgFileBackends[] = wfBackendForLegacyRepoConf( $repo );
+ $repo['backend'] = $repo['name'] . '-backend';
}
}
unset( $repo ); // no global pollution; destroy reference
-/*
- * Get file backend configuration for a given repo
- * configuration that lacks a backend parameter.
- * Also updates the repo config to use the backend.
- */
-function wfBackendForLegacyRepoConf( &$info ) {
- global $wgUploadDirectory;
- // Local vars that used to be FSRepo members...
- if ( !isset( $info['directory'] ) && $info['class'] === 'ForeignAPIRepo' ) {
- $info['directory'] = $wgUploadDirectory; // b/c
- }
- $directory = $info['directory'];
- $deletedDir = isset( $info['deletedDir'] )
- ? $info['deletedDir']
- : false;
- $thumbDir = isset( $info['thumbDir'] )
- ? $info['thumbDir']
- : "{$directory}/thumb";
- $fileMode = isset( $info['fileMode'] )
- ? $info['fileMode']
- : 0644;
-
- // Make a backend name (based on repo name)
- $backendName = $info['name'] . '-backend';
- // Update repo config to use this backend
- $info['backend'] = $backendName;
- // Disable "deleted" zone in repo config if deleted dir not set
- if ( $deletedDir !== false ) {
- $info['zones']['deleted'] = array(
- 'container' => 'media-deleted', 'directory' => '' );
- }
- // Get the FS backend configuration
- return array(
- 'name' => $backendName,
- 'class' => 'FSFileBackend',
- 'lockManager' => 'fsLockManager',
- 'containerPaths' => array(
- "media-public" => "{$directory}",
- "media-temp" => "{$directory}/temp",
- "media-thumb" => $thumbDir,
- "media-deleted" => $deletedDir
- ),
- 'fileMode' => $fileMode,
- );
-}
if ( is_null( $wgEnableAutoRotation ) ) {
// Only enable auto-rotation when the bitmap handler can rotate
wfRunHooks( 'AuthPluginSetup', array( &$wgAuth ) );
}
-# Register file lock managers
-LockManagerGroup::singleton()->register( $wgLockManagers );
-# Register file backends
-FileBackendGroup::singleton()->register( $wgFileBackends );
-
# Placeholders in case of DB error
$wgTitle = null;
// Give defaults for the basic zones...
foreach ( array( 'public', 'thumb', 'temp', 'deleted' ) as $zone ) {
if ( !isset( $this->zones[$zone] ) ) {
- if ( $zone === 'deleted' ) {
- $this->zones[$zone] = array(
- 'container' => null, // user must set this up
- 'directory' => '' // container root
- );
- } else {
- $this->zones[$zone] = array(
- 'container' => "media-$zone",
- 'directory' => '' // container root
- );
- }
+ $this->zones[$zone] = array(
+ 'container' => "media-$zone",
+ 'directory' => '' // container root
+ );
}
}
}
}
/**
- * Prepare all the zones for basic usage.
+ * Prepare a single zone or list of zones for usage.
* See initDeletedDir() for additional setup needed for the 'deleted' zone.
*
* @param $doZones Array Only do a particular zones
*/
protected function initZones( $doZones = array() ) {
$status = $this->newGood();
- $doZones = (array)$doZones; // string => array
- foreach ( $this->zones as $zone => $info ) {
- if ( $doZones && !in_array( $zone, $doZones ) ) {
- continue;
- }
+ foreach ( (array)$doZones as $zone ) {
$root = $this->getZonePath( $zone );
- if ( $root !== null ) {
+ if ( $root === null ) {
+ throw new MWException( "No '$zone' zone defined in the $this->name repo." );
+ } else {
$params = array( 'dir' => $this->getZonePath( $zone ) );
$status->merge( $this->backend->prepare( $params ) );
}
public function deleteBatch( $sourceDestPairs ) {
$backend = $this->backend; // convenience
- if ( !isset( $this->zones['deleted']['container'] ) ) {
- throw new MWException( __METHOD__.': no valid deletion archive directory' );
- }
-
// Try creating directories
$status = $this->initZones( array( 'public', 'deleted' ) );
if ( !$status->isOK() ) {
protected function __construct() {}
protected function __clone() {}
+ /**
+ * @return FileBackendGroup
+ */
public static function singleton() {
if ( self::$instance == null ) {
self::$instance = new self();
+ self::$instance->initFromGlobals();
}
return self::$instance;
}
/**
- * Destroy the singleton instance, so that a new one will be created next
- * time singleton() is called.
+ * Destroy the singleton instance
+ *
+ * @return void
*/
public static function destroySingleton() {
self::$instance = null;
}
+ /**
+ * Register file backends from the global variables
+ *
+ * @return void
+ */
+ protected function initFromGlobals() {
+ global $wgLocalFileRepo, $wgForeignFileRepos, $wgFileBackends;
+
+ // Register explicitly defined backends
+ $this->register( $wgFileBackends );
+
+ $autoBackends = array();
+ // Automatically create b/c backends for file repos...
+ $repos = array_merge( $wgForeignFileRepos, array( $wgLocalFileRepo ) );
+ foreach ( $repos as $info ) {
+ $backendName = $info['backend'];
+ if ( is_object( $backendName ) || isset( $this->backends[$backendName] ) ) {
+ continue; // already defined (or set to the object for some reason)
+ }
+ // Local vars that used to be FSRepo members...
+ $directory = $info['directory'];
+ $deletedDir = isset( $info['deletedDir'] )
+ ? $info['deletedDir']
+ : false; // deletion disabled
+ $thumbDir = isset( $info['thumbDir'] )
+ ? $info['thumbDir']
+ : "{$directory}/thumb";
+ $fileMode = isset( $info['fileMode'] )
+ ? $info['fileMode']
+ : 0644;
+ // Get the FS backend configuration
+ $autoBackends[] = array(
+ 'name' => $backendName,
+ 'class' => 'FSFileBackend',
+ 'lockManager' => 'fsLockManager',
+ 'containerPaths' => array(
+ "media-public" => "{$directory}",
+ "media-thumb" => $thumbDir,
+ "media-deleted" => $deletedDir,
+ "media-temp" => "{$directory}/temp"
+ ),
+ 'fileMode' => $fileMode,
+ );
+ }
+
+ // Register implicitly defined backends
+ $this->register( $autoBackends );
+ }
+
/**
* Register an array of file backend configurations
*
* @return void
* @throws MWException
*/
- public function register( array $configs ) {
+ protected function register( array $configs ) {
foreach ( $configs as $config ) {
if ( !isset( $config['name'] ) ) {
throw new MWException( "Cannot register a backend with no name." );
* Class to handle file lock manager registration
*
* @ingroup LockManager
+ * @author Aaron Schulz
*/
class LockManagerGroup {
protected static $instance = null;
protected function __construct() {}
protected function __clone() {}
+ /**
+ * @return LockManagerGroup
+ */
public static function singleton() {
if ( self::$instance == null ) {
self::$instance = new self();
+ self::$instance->initFromGlobals();
}
return self::$instance;
}
+ /**
+ * Register lock managers from the global variables
+ *
+ * @return void
+ */
+ protected function initFromGlobals() {
+ global $wgLockManagers;
+
+ $this->register( $wgLockManagers );
+ }
+
/**
* Register an array of file lock manager configurations
*
* @return void
* @throws MWException
*/
- public function register( array $configs ) {
+ protected function register( array $configs ) {
foreach ( $configs as $config ) {
if ( !isset( $config['name'] ) ) {
throw new MWException( "Cannot register a lock manager with no name." );
$wgStylePath = '/skins';
$wgExtensionAssetsPath = '/extensions';
$wgThumbnailScriptPath = false;
- $backend = new FSFileBackend( array(
- 'name' => 'local-backend',
- 'lockManager' => 'fsLockManager',
- 'containerPaths' => array(
- 'media-public' => wfTempDir() . '/test-repo/public',
- 'media-thumb' => wfTempDir() . '/test-repo/thumb',
- 'media-temp' => wfTempDir() . '/test-repo/temp',
- 'media-deleted' => wfTempDir() . '/test-repo/delete',
- )
- ) );
$wgLocalFileRepo = array(
'class' => 'LocalRepo',
'name' => 'local',
'url' => 'http://example.com/images',
'hashLevels' => 2,
'transformVia404' => false,
- 'backend' => $backend,
- 'zones' => array( 'deleted' => array(
- 'container' => 'media-deleted', 'directory' => '' ) )
+ 'backend' => new FSFileBackend( array(
+ 'name' => 'local-backend',
+ 'lockManager' => 'fsLockManager',
+ 'containerPaths' => array(
+ 'media-public' => wfTempDir() . '/test-repo/public',
+ 'media-thumb' => wfTempDir() . '/test-repo/thumb',
+ 'media-temp' => wfTempDir() . '/test-repo/temp',
+ 'media-deleted' => wfTempDir() . '/test-repo/delete',
+ )
+ ) )
);
$wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface';
$wgNamespaceAliases['Image'] = NS_FILE;
$wgNamespaceAliases['Image_talk'] = $this->savedWeirdGlobals['image_talk_alias'];
// Restore backends
- FileBackendGroup::destroySingleton();
- FileBackendGroup::singleton()->register( $GLOBALS['wgFileBackends'] );
RepoGroup::destroySingleton();
}
'url' => 'http://example.com/images',
'hashLevels' => 2,
'transformVia404' => false,
- 'backend' => 'local-backend'
+ 'backend' => new FSFileBackend( array(
+ 'name' => 'local-backend',
+ 'lockManager' => 'nullLockManager',
+ 'containerPaths' => array(
+ 'media-public' => "$this->uploadDir",
+ 'media-thumb' => "$this->uploadDir/thumb",
+ )
+ ) )
),
'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
'wgStylePath' => '/skins',
$GLOBALS['wgOut'] = $context->getOutput();
$GLOBALS['wgUser'] = $context->getUser();
- FileBackendGroup::destroySingleton(); // reset
- $backend = array(
- 'name' => 'local-backend',
- 'class' => 'FSFileBackend',
- 'lockManager' => 'nullLockManager',
- 'containerPaths' => array(
- 'media-public' => $this->uploadDir,
- 'media-thumb' => $this->uploadDir . '/thumb' )
- );
- FileBackendGroup::singleton()->register( array( $backend ) );
-
global $wgHooks;
$wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup';
RepoGroup::destroySingleton();
LinkCache::singleton()->clear();
- FileBackendGroup::destroySingleton();
$this->teardownUploadDir( $this->uploadDir );
}