12use InvalidArgumentException;
26use Wikimedia\Mime\MimeAnalyzer;
47 private MimeAnalyzer $mimeAnalyzer;
68 MimeAnalyzer $mimeAnalyzer,
73 $this->options = $options;
74 $this->srvCache = $srvCache;
75 $this->wanCache = $wanCache;
76 $this->mimeAnalyzer = $mimeAnalyzer;
77 $this->lmgFactory = $lmgFactory;
78 $this->tmpFileFactory = $tmpFileFactory;
79 $this->telemetry = $telemetry;
88 foreach ( $repos as $info ) {
89 $backendName = $info[
'backend'];
90 if ( is_object( $backendName ) || isset( $this->backends[$backendName] ) ) {
93 $repoName = $info[
'name'];
95 $directory = $info[
'directory'];
97 $deletedDir = $info[
'deletedDir'] ??
false;
98 $thumbDir = $info[
'thumbDir'] ??
"{$directory}/thumb";
99 $transcodedDir = $info[
'transcodedDir'] ??
"{$directory}/transcoded";
100 $lockManager = $info[
'lockManager'] ??
'fsLockManager';
103 'name' => $backendName,
104 'class' => FSFileBackend::class,
105 'lockManager' => $lockManager,
106 'containerPaths' => [
107 "{$repoName}-public" =>
"{$directory}",
108 "{$repoName}-thumb" => $thumbDir,
109 "{$repoName}-transcoded" => $transcodedDir,
110 "{$repoName}-deleted" => $deletedDir,
111 "{$repoName}-temp" =>
"{$directory}/temp"
113 'fileMode' => $info[
'fileMode'] ?? 0644,
128 protected function register( array $configs, $readOnlyReason = null ) {
129 foreach ( $configs as $config ) {
130 if ( !isset( $config[
'name'] ) ) {
131 throw new InvalidArgumentException(
"Cannot register a backend with no name." );
133 $name = $config[
'name'];
134 if ( isset( $this->backends[$name] ) ) {
135 throw new LogicException(
"Backend with name '$name' already registered." );
136 } elseif ( !isset( $config[
'class'] ) ) {
137 throw new InvalidArgumentException(
"Backend with name '$name' has no class." );
139 $class = $config[
'class'];
141 $config[
'domainId'] ??= $config[
'wikiId'] ?? $this->options->get(
'fallbackWikiId' );
142 $config[
'readOnly'] ??= $readOnlyReason;
144 unset( $config[
'class'] );
145 $this->backends[$name] = [
159 public function get( $name ) {
161 if ( !isset( $this->backends[$name][
'instance'] ) ) {
162 $config = $this->
config( $name );
164 $class = $config[
'class'];
166 if ( $class === FileBackendMultiWrite::class || $class === \FileBackendMultiWrite::class ) {
168 foreach ( $config[
'backends'] as $index => $beConfig ) {
169 if ( isset( $beConfig[
'template'] ) ) {
172 $config[
'backends'][$index] += $this->
config( $beConfig[
'template'] );
177 $this->backends[$name][
'instance'] =
new $class( $config );
180 return $this->backends[$name][
'instance'];
190 if ( !isset( $this->backends[$name] ) ) {
191 throw new InvalidArgumentException(
"No backend defined with the name '$name'." );
194 $config = $this->backends[$name][
'config'];
201 'asyncHandler' => DeferredUpdates::addCallableUpdate( ... ),
203 'tmpFileFactory' => $this->tmpFileFactory,
204 'statusWrapper' => Status::wrap( ... ),
205 'wanCache' => $this->wanCache,
206 'srvCache' => $this->srvCache,
207 'logger' => LoggerFactory::getInstance(
'FileOperation' ),
208 'telemetry' => $this->telemetry,
214 'class' => $this->backends[$name][
'class'],
216 $this->lmgFactory->getLockManagerGroup( $config[
'domainId'] )
217 ->get( $config[
'lockManager'] ),
230 if ( $backend !==
null && isset( $this->backends[$backend] ) ) {
231 return $this->
get( $backend );
247 $type = $this->mimeAnalyzer->getMimeTypeFromExtensionOrNull( $ext );
249 if ( !$type && $fsPath ) {
250 $type = $this->mimeAnalyzer->guessMimeType( $fsPath,
false );
251 } elseif ( !$type && $content !==
null && $content !==
'' ) {
252 $tmpFile = $this->tmpFileFactory->newTempFSFile(
'mime_',
'' );
253 file_put_contents( $tmpFile->getPath(), $content );
254 $type = $this->mimeAnalyzer->guessMimeType( $tmpFile->getPath(),
false );
256 return $type ?:
'unknown/unknown';
260class_alias( FileBackendGroup::class,
'FileBackendGroup' );
wfResetOutputBuffers( $resetGzipEncoding=true)
Clear away any user-level output buffers, discarding contents.
A class containing constants representing the names of configuration variables.
const FileBackends
Name constant for the FileBackends setting, for use with Config::get()
const LocalFileRepo
Name constant for the LocalFileRepo setting, for use with Config::get()
const ForeignFileRepos
Name constant for the ForeignFileRepos setting, for use with Config::get()
const DirectoryMode
Name constant for the DirectoryMode setting, for use with Config::get()