In FileBackendBase/FileBackend:
[lhc/web/wiklou.git] / includes / filerepo / backend / FileBackendGroup.php
1 <?php
2 /**
3 * @file
4 * @ingroup FileBackend
5 * @author Aaron Schulz
6 */
7
8 /**
9 * Class to handle file backend registration
10 *
11 * @ingroup FileBackend
12 * @since 1.19
13 */
14 class FileBackendGroup {
15 protected static $instance = null;
16
17 /** @var Array (name => ('class' => string, 'config' => array, 'instance' => object)) */
18 protected $backends = array();
19
20 protected function __construct() {}
21 protected function __clone() {}
22
23 /**
24 * @return FileBackendGroup
25 */
26 public static function singleton() {
27 if ( self::$instance == null ) {
28 self::$instance = new self();
29 self::$instance->initFromGlobals();
30 }
31 return self::$instance;
32 }
33
34 /**
35 * Destroy the singleton instance
36 *
37 * @return void
38 */
39 public static function destroySingleton() {
40 self::$instance = null;
41 }
42
43 /**
44 * Register file backends from the global variables
45 *
46 * @return void
47 */
48 protected function initFromGlobals() {
49 global $wgLocalFileRepo, $wgForeignFileRepos, $wgFileBackends;
50
51 // Register explicitly defined backends
52 $this->register( $wgFileBackends );
53
54 $autoBackends = array();
55 // Automatically create b/c backends for file repos...
56 $repos = array_merge( $wgForeignFileRepos, array( $wgLocalFileRepo ) );
57 foreach ( $repos as $info ) {
58 $backendName = $info['backend'];
59 if ( is_object( $backendName ) || isset( $this->backends[$backendName] ) ) {
60 continue; // already defined (or set to the object for some reason)
61 }
62 $repoName = $info['name'];
63 // Local vars that used to be FSRepo members...
64 $directory = $info['directory'];
65 $deletedDir = isset( $info['deletedDir'] )
66 ? $info['deletedDir']
67 : false; // deletion disabled
68 $thumbDir = isset( $info['thumbDir'] )
69 ? $info['thumbDir']
70 : "{$directory}/thumb";
71 $fileMode = isset( $info['fileMode'] )
72 ? $info['fileMode']
73 : 0644;
74 // Get the FS backend configuration
75 $autoBackends[] = array(
76 'name' => $backendName,
77 'class' => 'FSFileBackend',
78 'lockManager' => 'fsLockManager',
79 'containerPaths' => array(
80 "{$repoName}-public" => "{$directory}",
81 "{$repoName}-thumb" => $thumbDir,
82 "{$repoName}-deleted" => $deletedDir,
83 "{$repoName}-temp" => "{$directory}/temp"
84 ),
85 'fileMode' => $fileMode,
86 );
87 }
88
89 // Register implicitly defined backends
90 $this->register( $autoBackends );
91 }
92
93 /**
94 * Register an array of file backend configurations
95 *
96 * @param $configs Array
97 * @return void
98 * @throws MWException
99 */
100 protected function register( array $configs ) {
101 foreach ( $configs as $config ) {
102 if ( !isset( $config['name'] ) ) {
103 throw new MWException( "Cannot register a backend with no name." );
104 }
105 $name = $config['name'];
106 if ( !isset( $config['class'] ) ) {
107 throw new MWException( "Cannot register backend `{$name}` with no class." );
108 }
109 $class = $config['class'];
110
111 unset( $config['class'] ); // backend won't need this
112 $this->backends[$name] = array(
113 'class' => $class,
114 'config' => $config,
115 'instance' => null
116 );
117 }
118 }
119
120 /**
121 * Get the backend object with a given name
122 *
123 * @param $name string
124 * @return FileBackendBase
125 * @throws MWException
126 */
127 public function get( $name ) {
128 if ( !isset( $this->backends[$name] ) ) {
129 throw new MWException( "No backend defined with the name `$name`." );
130 }
131 // Lazy-load the actual backend instance
132 if ( !isset( $this->backends[$name]['instance'] ) ) {
133 $class = $this->backends[$name]['class'];
134 $config = $this->backends[$name]['config'];
135 $this->backends[$name]['instance'] = new $class( $config );
136 }
137 return $this->backends[$name]['instance'];
138 }
139
140 /**
141 * Get an appropriate backend object from a storage path
142 *
143 * @param $storagePath string
144 * @return FileBackendBase|null Backend or null on failure
145 */
146 public function backendFromPath( $storagePath ) {
147 list( $backend, $c, $p ) = FileBackend::splitStoragePath( $storagePath );
148 if ( $backend !== null && isset( $this->backends[$backend] ) ) {
149 return $this->get( $backend );
150 }
151 return null;
152 }
153 }