https://www.mediawiki.org/wiki/Special:Code/MediaWiki/104531
Revision: 104531 Author: aaron Date: 2011-11-29 01:26:05 +0000 (Tue, 29 Nov 2011) Log Message: ----------- * Moved wikiKey stuff from FileRepo to FileBackend (renamed to wikiId) and made it more transparent * Added setup code and config vars for backends and lock managers * Added sanity check to wfMkDirParents() Modified Paths: -------------- branches/FileBackend/phase3/includes/AutoLoader.php branches/FileBackend/phase3/includes/DefaultSettings.php branches/FileBackend/phase3/includes/GlobalFunctions.php branches/FileBackend/phase3/includes/Setup.php branches/FileBackend/phase3/includes/filerepo/FileRepo.php branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php branches/FileBackend/phase3/includes/filerepo/backend/FileBackendGroup.php Added Paths: ----------- branches/FileBackend/phase3/includes/filerepo/backend/FileLockManagerGroup.php Modified: branches/FileBackend/phase3/includes/AutoLoader.php =================================================================== --- branches/FileBackend/phase3/includes/AutoLoader.php 2011-11-29 01:21:07 UTC (rev 104530) +++ branches/FileBackend/phase3/includes/AutoLoader.php 2011-11-29 01:26:05 UTC (rev 104531) @@ -485,12 +485,13 @@ 'TempFSFile' => 'includes/filerepo/file/TempFSFile.php', # includes/filerepo/backend - 'FileBackendGroup' => 'includes/filerepo/backend/FileBackendGroup', + 'FileBackendGroup' => 'includes/filerepo/backend/FileBackendGroup.php', 'FileBackendBase' => 'includes/filerepo/backend/FileBackend.php', 'FileBackend' => 'includes/filerepo/backend/FileBackend.php', 'FileBackendMultiWrite' => 'includes/filerepo/backend/FileBackendMultiWrite.php', 'FSFileBackend' => 'includes/filerepo/backend/FSFileBackend.php', 'FileIterator' => 'includes/filerepo/backend/FSFileBackend.php', + 'FileLockManagerGroup' => 'includes/filerepo/backend/FileLockManagerGroup.php', 'FileLockManager' => 'includes/filerepo/backend/FileLockManager.php', 'FSFileLockManager' => 'includes/filerepo/backend/FileLockManager.php', 'DBFileLockManager' => 'includes/filerepo/backend/FileLockManager.php', Modified: branches/FileBackend/phase3/includes/DefaultSettings.php =================================================================== --- branches/FileBackend/phase3/includes/DefaultSettings.php 2011-11-29 01:21:07 UTC (rev 104530) +++ branches/FileBackend/phase3/includes/DefaultSettings.php 2011-11-29 01:26:05 UTC (rev 104531) @@ -367,6 +367,27 @@ $wgUseInstantCommons = false; /** + * File backend structure configuration. + * This is an array of file backend configuration arrays. + * Each backend configuration has the following parameters: + * 'name' : A unique name for the backend + * 'class' : The file backend class to use + * 'wikiId' : A unique string that identifies the wiki (container prefix) + * 'lockManager' : The name of a lock manager (see $wgFileLockManagers) + * Additional parameters are specific to the class used. + */ +$wgFileBackends = array(); + +/** + * Array of configuration arrays for each lock manager. + * Each backend configuration has the following parameters: + * 'name' : A unique name for the lock manger + * 'class' : The lock manger class to use + * Additional parameters are specific to the class used. + */ +$wgFileLockManagers = array(); + +/** * Show EXIF data, on by default if available. * Requires PHP's EXIF extension: http://www.php.net/manual/en/ref.exif.php * Modified: branches/FileBackend/phase3/includes/GlobalFunctions.php =================================================================== --- branches/FileBackend/phase3/includes/GlobalFunctions.php 2011-11-29 01:21:07 UTC (rev 104530) +++ branches/FileBackend/phase3/includes/GlobalFunctions.php 2011-11-29 01:26:05 UTC (rev 104531) @@ -2379,6 +2379,10 @@ function wfMkdirParents( $dir, $mode = null, $caller = null ) { global $wgDirectoryMode; + if ( FileBackend::isStoragePath( $dir ) ) { // sanity + throw new MWException( "Given storage path `$dir`."); + } + if ( !is_null( $caller ) ) { wfDebug( "$caller: called wfMkdirParents($dir)\n" ); } Modified: branches/FileBackend/phase3/includes/Setup.php =================================================================== --- branches/FileBackend/phase3/includes/Setup.php 2011-11-29 01:21:07 UTC (rev 104530) +++ branches/FileBackend/phase3/includes/Setup.php 2011-11-29 01:26:05 UTC (rev 104531) @@ -115,6 +115,15 @@ $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; /** + * Initialise $wgFileLockManagers to include basic FS version + */ +$wgFileLockManagers[] = array( + 'name' => 'fsLockManager', + 'class' => 'FSFileLockManager', + 'lockDirectory' => $wgUploadDirectory, +); + +/** * Initialise $wgLocalFileRepo from backwards-compatible settings */ if ( !$wgLocalFileRepo ) { @@ -179,6 +188,7 @@ $wgForeignFileRepos[] = array( 'class' => 'ForeignAPIRepo', 'name' => 'wikimediacommons', + 'directory' => $wgUploadDirectory, 'apibase' => 'http://commons.wikimedia.org/w/api.php', 'hashLevels' => 2, 'fetchDescription' => true, @@ -186,7 +196,57 @@ 'apiThumbCacheExpiry' => 86400, ); } +/* + * Add on default file backend config for repos to $wgFileBackends + */ +if ( !isset( $wgLocalFileRepo['backend'] ) ) { + $wgFileBackends[] = wfBackendForLegacyRepoConf( $wgLocalFileRepo ); +} +foreach ( $wgForeignFileRepos as &$repo ) { + if ( !isset( $repo['backend'] ) ) { + $wgFileBackends[] = wfBackendForLegacyRepoConf( $repo ); + } +} +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 ) { + // Local vars that used to be FSRepo members... + $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; + // Get the FS backend configuration + return array( + 'name' => $backendName, + 'class' => 'FSFileBackend', + 'lockManager' => new FSFileLockManager( + array( 'lockDirectory' => "{$directory}/locks" ) + ), + 'containerPaths' => array( + "public" => "{$directory}", + "temp" => "{$directory}/temp", + "thumb" => $thumbDir, + "deleted" => $deletedDir + ), + 'fileMode' => $fileMode, + ); +} + if ( is_null( $wgEnableAutoRotation ) ) { // Only enable auto-rotation when the bitmap handler can rotate $wgEnableAutoRotation = BitmapHandler::canRotate(); @@ -459,6 +519,11 @@ wfRunHooks( 'AuthPluginSetup', array( &$wgAuth ) ); } +# Register file lock managers +FileLockManagerGroup::singleton()->register( $wgFileLockManagers ); +# Register file backends +FileBackendGroup::singleton()->register( $wgFileBackends ); + # Placeholders in case of DB error $wgTitle = null; Modified: branches/FileBackend/phase3/includes/filerepo/FileRepo.php =================================================================== --- branches/FileBackend/phase3/includes/filerepo/FileRepo.php 2011-11-29 01:21:07 UTC (rev 104530) +++ branches/FileBackend/phase3/includes/filerepo/FileRepo.php 2011-11-29 01:26:05 UTC (rev 104531) @@ -23,8 +23,6 @@ /** @var Array Map of zones to config */ protected $zones = array(); - protected $wikiKey; // unique wiki identifier - var $thumbScriptUrl, $transformVia404; var $descBaseUrl, $scriptDirUrl, $scriptExtension, $articleUrl; var $fetchDescription, $initialCapital; @@ -46,6 +44,7 @@ $this->url = isset( $info['url'] ) ? $info['url'] : false; // a subclass will need to set the URL (e.g. ForeignAPIRepo) + $this->backend = FileBackendGroup::singleton()->get( $info['backend'] ); // Optional settings that can have no value $optionalSettings = array( @@ -63,9 +62,6 @@ $this->initialCapital = isset( $info['initialCapital'] ) ? $info['initialCapital'] : MWNamespace::isCapitalized( NS_FILE ); - $this->wikiKey = isset( $info['wikiKey'] ) - ? $info['wikiKey'] - : wfWikiID(); $this->thumbUrl = isset( $info['thumbUrl'] ) ? $info['thumbUrl'] : "{$this->url}/thumb"; @@ -76,85 +72,23 @@ ? $info['deletedHashLevels'] : $this->hashLevels; $this->transformVia404 = !empty( $info['transformVia404'] ); - - $this->zones = array(); - // New backend & zone config style - if ( isset( $info['backend'] ) ) { - $this->backend = $info['backend']; - if ( isset( $info['zones'] ) ) { - $this->zones = $info['zones']; - } - $prefix = $this->getContainerPrefix(); - // 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' => "{$prefix}{$zone}", - 'directory' => '' // container root - ); - } - } - } - // Old fashioned backend (FS) config - } else { - $this->initLegacyConfig( $info ); - } - } - - /** - * Handle backend and zone settings for old config style - * - * @param $info Array - * @return void - */ - protected function initLegacyConfig( array $info ) { - // Local vars that used to be FSRepo members... - $directory = $info['directory']; - $deletedDir = isset( $info['deletedDir'] ) - ? $info['deletedDir'] - : false; - if ( isset( $info['thumbDir'] ) ) { - $thumbDir = $info['thumbDir']; - } else { - $thumbDir = "{$directory}/thumb"; - } - $fileMode = isset( $info['fileMode'] ) - ? $info['fileMode'] - : 0644; - - // Get the FS backend from configuration... - $prefix = $this->getContainerPrefix(); - $config = array( - 'name' => "{$this->name}-backend", - 'lockManager' => new FSFileLockManager( - array( 'lockDirectory' => "{$directory}/locks" ) - ), - 'containerPaths' => array( - "{$prefix}public" => "{$directory}", - "{$prefix}temp" => "{$directory}/temp", - "{$prefix}thumb" => $thumbDir, - "{$prefix}deleted" => $deletedDir - ), - 'fileMode' => $fileMode, - ); - $this->backend = new FSFileBackend( $config ); - - // Set the basic zones... + $this->zones = isset( $info['zones'] ) + ? $info['zones'] + : array(); + // Give defaults for the basic zones... foreach ( array( 'public', 'thumb', 'temp', 'deleted' ) as $zone ) { if ( !isset( $this->zones[$zone] ) ) { - if ( $zone === 'deleted' && $deletedDir === false ) { - continue; // user must set this up + if ( $zone === 'deleted' ) { + $this->zones[$zone] = array( + 'container' => null, // user must set this up + 'directory' => '' // container root + ); + } else { + $this->zones[$zone] = array( + 'container' => $zone, + 'directory' => '' // container root + ); } - $this->zones[$zone] = array( - 'container' => "{$prefix}{$zone}", - 'directory' => '' // container root - ); } } } @@ -169,15 +103,6 @@ } /** - * Get the container prefix from the wiki key - * - * @return string - */ - protected function getContainerPrefix() { - return strlen( $this->wikiKey ) ? "{$this->wikiKey}-" : ""; - } - - /** * Prepare all the zones for basic usage. * See initDeletedDir() for additional setup needed for the 'deleted' zone. * Modified: branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php =================================================================== --- branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php 2011-11-29 01:21:07 UTC (rev 104530) +++ branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php 2011-11-29 01:26:05 UTC (rev 104531) @@ -23,6 +23,7 @@ */ abstract class FileBackendBase { protected $name; // unique backend name + protected $wikiId; // unique wiki name /** @var FileLockManager */ protected $lockManager; @@ -31,12 +32,16 @@ * This should only be called from within FileRepo classes. * $config includes: * 'name' : The name of this backend + * 'wikiId' : Prefix to container names that is unique to this wiki * 'lockManager' : The file lock manager to use * * @param $config Array */ public function __construct( array $config ) { $this->name = $config['name']; + $this->wikiId = isset( $config['wikiId'] ) + ? $config['wikiId'] + : wfWikiID(); $this->lockManager = $config['lockManager']; } @@ -535,6 +540,7 @@ if ( $parts[0] !== null ) { // either all null or all not null list( $backend, $container, $relPath ) = $parts; if ( $backend === $this->name ) { // sanity + $container = $this->fullContainerName( $container ); $relPath = $this->resolveContainerPath( $container, $relPath ); if ( $relPath !== null ) { return array( $container, $relPath ); // (container, path) @@ -545,6 +551,20 @@ } /** + * Get the full container name, including the wiki ID prefix + * + * @param $container string + * @return string + */ + final protected function fullContainerName( $container ) { + if ( $this->wikiId != '' ) { + return "{$this->wikiId}-$container"; + } else { + return $container; + } + } + + /** * Resolve a storage path relative to a particular container. * This is for internal use for backends, such as encoding or * perhaps getting absolute paths (e.g. file system based backends). Modified: branches/FileBackend/phase3/includes/filerepo/backend/FileBackendGroup.php =================================================================== --- branches/FileBackend/phase3/includes/filerepo/backend/FileBackendGroup.php 2011-11-29 01:21:07 UTC (rev 104530) +++ branches/FileBackend/phase3/includes/filerepo/backend/FileBackendGroup.php 2011-11-29 01:26:05 UTC (rev 104531) @@ -28,28 +28,30 @@ } /** - * Register a file backend from configuration + * Register an array of file backend configurations * - * @param $config Array + * @param $configs Array * @return void * @throws MWException */ - public function register( array $config ) { - if ( !isset( $config['name'] ) ) { - throw new MWException( "Cannot register a backend with no name." ); + public function register( array $configs ) { + foreach ( $configs as $config ) { + if ( !isset( $config['name'] ) ) { + throw new MWException( "Cannot register a backend with no name." ); + } + $name = $config['name']; + if ( !isset( $config['class'] ) ) { + throw new MWException( "Cannot register backend `{$name}` with no class." ); + } + $class = $config['class']; + + unset( $config['class'] ); // backend won't need this + $this->backends[$name] = array( + 'class' => $class, + 'config' => $config, + 'instance' => null + ); } - $name = $config['name']; - if ( !isset( $config['class'] ) ) { - throw new MWException( "Cannot register backend `{$name}` with no class." ); - } - $class = $config['class']; - - unset( $config['class'] ); // backend won't need this - $this->backends[$name] = array( - 'class' => $class, - 'config' => $config, - 'instance' => null - ); } /** @@ -59,7 +61,7 @@ * @return FileBackendBase * @throws MWException */ - public function getBackend( $name ) { + public function get( $name ) { if ( !isset( $this->backends[$name] ) ) { throw new MWException( "No backend defined with the name `$name`." ); } Added: branches/FileBackend/phase3/includes/filerepo/backend/FileLockManagerGroup.php =================================================================== --- branches/FileBackend/phase3/includes/filerepo/backend/FileLockManagerGroup.php (rev 0) +++ branches/FileBackend/phase3/includes/filerepo/backend/FileLockManagerGroup.php 2011-11-29 01:26:05 UTC (rev 104531) @@ -0,0 +1,68 @@ +<?php +/** + * Class to handle file lock manager registration + */ +class FileLockManagerGroup { + protected static $instance = null; + + /** @var Array of (name => ('class' =>, 'config' =>, 'instance' =>)) */ + protected $managers = array(); + + protected function __construct() {} + protected function __clone() {} + + public static function singleton() { + if ( self::$instance == null ) { + self::$instance = new self(); + } + return self::$instance; + } + + /** + * Register an array of file lock manager configurations + * + * @param $configs Array + * @return void + * @throws MWException + */ + final public function register( array $configs ) { + foreach ( $configs as $config ) { + if ( !isset( $config['name'] ) ) { + throw new MWException( "Cannot register a lock manager with no name." ); + } + $name = $config['name']; + if ( !isset( $config['class'] ) ) { + throw new MWException( "Cannot register lock manager `{$name}` with no class." ); + } + $class = $config['class']; + + unset( $config['class'] ); // lock manager won't need this + $this->managers[$name] = array( + 'class' => $class, + 'config' => $config, + 'instance' => null + ); + } + } + + + /** + * Get the lock manager object with a given name + * + * @param $name string + * @return FileLockManager + * @throws MWException + */ + public function get( $name ) { + if ( !isset( $this->managers[$name] ) ) { + throw new MWException( "No lock manager defined with the name `$name`." ); + } + // Lazy-load the actual backend instance + if ( !isset( $this->managers[$name]['instance'] ) ) { + $class = $this->managers[$name]['class']; + $config = $this->managers[$name]['config']; + $this->managers[$name]['instance'] = new $class( $config ); + } + return $this->managers[$name]['instance']; + } +} Property changes on: branches/FileBackend/phase3/includes/filerepo/backend/FileLockManagerGroup.php ___________________________________________________________________ Added: svn:eol-style + native _______________________________________________ MediaWiki-CVS mailing list MediaWiki-CVS@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs