Completed
Push — master ( 6ee282...61bb2d )
by Marcel
21:33
created
lib/private/Repair/RepairMimeTypes.php 2 patches
Indentation   +469 added lines, -469 removed lines patch added patch discarded remove patch
@@ -17,473 +17,473 @@
 block discarded – undo
17 17
 use OCP\Migration\IRepairStep;
18 18
 
19 19
 class RepairMimeTypes implements IRepairStep {
20
-	private bool $dryRun = false;
21
-	private int $changeCount = 0;
22
-
23
-	/** @var int */
24
-	protected int $folderMimeTypeId;
25
-
26
-	public function __construct(
27
-		protected IConfig $config,
28
-		protected IAppConfig $appConfig,
29
-		protected IDBConnection $connection,
30
-	) {
31
-	}
32
-
33
-	public function getName(): string {
34
-		return 'Repair mime types';
35
-	}
36
-
37
-	/**
38
-	 * @throws Exception
39
-	 */
40
-	private function updateMimetypes($updatedMimetypes): IResult|int|null {
41
-		if ($this->dryRun) {
42
-			$this->changeCount += count($updatedMimetypes);
43
-			return null;
44
-		}
45
-
46
-		$query = $this->connection->getQueryBuilder();
47
-		$query->select('id')
48
-			->from('mimetypes')
49
-			->where($query->expr()->eq('mimetype', $query->createParameter('mimetype'), IQueryBuilder::PARAM_INT));
50
-		$insert = $this->connection->getQueryBuilder();
51
-		$insert->insert('mimetypes')
52
-			->setValue('mimetype', $insert->createParameter('mimetype'));
53
-
54
-		if (empty($this->folderMimeTypeId)) {
55
-			$query->setParameter('mimetype', 'httpd/unix-directory');
56
-			$result = $query->execute();
57
-			$this->folderMimeTypeId = (int)$result->fetchOne();
58
-			$result->closeCursor();
59
-		}
60
-
61
-		$update = $this->connection->getQueryBuilder();
62
-		$update->update('filecache')
63
-			->runAcrossAllShards()
64
-			->set('mimetype', $update->createParameter('mimetype'))
65
-			->where($update->expr()->neq('mimetype', $update->createParameter('mimetype'), IQueryBuilder::PARAM_INT))
66
-			->andWhere($update->expr()->neq('mimetype', $update->createParameter('folder'), IQueryBuilder::PARAM_INT))
67
-			->andWhere($update->expr()->iLike('name', $update->createParameter('name')))
68
-			->setParameter('folder', $this->folderMimeTypeId);
69
-
70
-		$count = 0;
71
-		foreach ($updatedMimetypes as $extension => $mimetype) {
72
-			// get target mimetype id
73
-			$query->setParameter('mimetype', $mimetype);
74
-			$result = $query->execute();
75
-			$mimetypeId = (int)$result->fetchOne();
76
-			$result->closeCursor();
77
-
78
-			if (!$mimetypeId) {
79
-				// insert mimetype
80
-				$insert->setParameter('mimetype', $mimetype);
81
-				$insert->execute();
82
-				$mimetypeId = $insert->getLastInsertId();
83
-			}
84
-
85
-			// change mimetype for files with x extension
86
-			$update->setParameter('mimetype', $mimetypeId)
87
-				->setParameter('name', '%' . $this->connection->escapeLikeParameter('.' . $extension));
88
-			$count += $update->execute();
89
-		}
90
-
91
-		return $count;
92
-	}
93
-
94
-	/**
95
-	 * @throws Exception
96
-	 * @since 12.0.0.14
97
-	 */
98
-	private function introduceImageTypes(): IResult|int|null {
99
-		$updatedMimetypes = [
100
-			'jp2' => 'image/jp2',
101
-			'webp' => 'image/webp',
102
-		];
103
-
104
-		return $this->updateMimetypes($updatedMimetypes);
105
-	}
106
-
107
-	/**
108
-	 * @throws Exception
109
-	 * @since 12.0.0.13
110
-	 */
111
-	private function introduceWindowsProgramTypes(): IResult|int|null {
112
-		$updatedMimetypes = [
113
-			'htaccess' => 'text/plain',
114
-			'bat' => 'application/x-msdos-program',
115
-			'cmd' => 'application/cmd',
116
-		];
117
-
118
-		return $this->updateMimetypes($updatedMimetypes);
119
-	}
120
-
121
-	/**
122
-	 * @throws Exception
123
-	 * @since 13.0.0.0
124
-	 */
125
-	private function introduceLocationTypes(): IResult|int|null {
126
-		$updatedMimetypes = [
127
-			'gpx' => 'application/gpx+xml',
128
-			'kml' => 'application/vnd.google-earth.kml+xml',
129
-			'kmz' => 'application/vnd.google-earth.kmz',
130
-			'tcx' => 'application/vnd.garmin.tcx+xml',
131
-		];
132
-
133
-		return $this->updateMimetypes($updatedMimetypes);
134
-	}
135
-
136
-	/**
137
-	 * @throws Exception
138
-	 * @since 13.0.0.3
139
-	 */
140
-	private function introduceInternetShortcutTypes(): IResult|int|null {
141
-		$updatedMimetypes = [
142
-			'url' => 'application/internet-shortcut',
143
-			'webloc' => 'application/internet-shortcut'
144
-		];
145
-
146
-		return $this->updateMimetypes($updatedMimetypes);
147
-	}
148
-
149
-	/**
150
-	 * @throws Exception
151
-	 * @since 13.0.0.6
152
-	 */
153
-	private function introduceStreamingTypes(): IResult|int|null {
154
-		$updatedMimetypes = [
155
-			'm3u' => 'audio/mpegurl',
156
-			'm3u8' => 'audio/mpegurl',
157
-			'pls' => 'audio/x-scpls'
158
-		];
159
-
160
-		return $this->updateMimetypes($updatedMimetypes);
161
-	}
162
-
163
-	/**
164
-	 * @throws Exception
165
-	 * @since 14.0.0.8
166
-	 */
167
-	private function introduceVisioTypes(): IResult|int|null {
168
-		$updatedMimetypes = [
169
-			'vsdm' => 'application/vnd.visio',
170
-			'vsdx' => 'application/vnd.visio',
171
-			'vssm' => 'application/vnd.visio',
172
-			'vssx' => 'application/vnd.visio',
173
-			'vstm' => 'application/vnd.visio',
174
-			'vstx' => 'application/vnd.visio',
175
-		];
176
-
177
-		return $this->updateMimetypes($updatedMimetypes);
178
-	}
179
-
180
-	/**
181
-	 * @throws Exception
182
-	 * @since 14.0.0.10
183
-	 */
184
-	private function introduceComicbookTypes(): IResult|int|null {
185
-		$updatedMimetypes = [
186
-			'cb7' => 'application/comicbook+7z',
187
-			'cba' => 'application/comicbook+ace',
188
-			'cbr' => 'application/comicbook+rar',
189
-			'cbt' => 'application/comicbook+tar',
190
-			'cbtc' => 'application/comicbook+truecrypt',
191
-			'cbz' => 'application/comicbook+zip',
192
-		];
193
-
194
-		return $this->updateMimetypes($updatedMimetypes);
195
-	}
196
-
197
-	/**
198
-	 * @throws Exception
199
-	 * @since 20.0.0.5
200
-	 */
201
-	private function introduceOpenDocumentTemplates(): IResult|int|null {
202
-		$updatedMimetypes = [
203
-			'ott' => 'application/vnd.oasis.opendocument.text-template',
204
-			'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
205
-			'otp' => 'application/vnd.oasis.opendocument.presentation-template',
206
-			'otg' => 'application/vnd.oasis.opendocument.graphics-template',
207
-		];
208
-
209
-		return $this->updateMimetypes($updatedMimetypes);
210
-	}
211
-
212
-	/**
213
-	 * @throws Exception
214
-	 * @since 21.0.0.7
215
-	 */
216
-	private function introduceOrgModeType(): IResult|int|null {
217
-		$updatedMimetypes = [
218
-			'org' => 'text/org'
219
-		];
220
-
221
-		return $this->updateMimetypes($updatedMimetypes);
222
-	}
223
-
224
-	/**
225
-	 * @throws Exception
226
-	 * @since 23.0.0.2
227
-	 */
228
-	private function introduceFlatOpenDocumentType(): IResult|int|null {
229
-		$updatedMimetypes = [
230
-			'fodt' => 'application/vnd.oasis.opendocument.text-flat-xml',
231
-			'fods' => 'application/vnd.oasis.opendocument.spreadsheet-flat-xml',
232
-			'fodg' => 'application/vnd.oasis.opendocument.graphics-flat-xml',
233
-			'fodp' => 'application/vnd.oasis.opendocument.presentation-flat-xml',
234
-		];
235
-
236
-		return $this->updateMimetypes($updatedMimetypes);
237
-	}
238
-
239
-	/**
240
-	 * @throws Exception
241
-	 * @since 25.0.0.2
242
-	 */
243
-	private function introduceOnlyofficeFormType(): IResult|int|null {
244
-		$updatedMimetypes = [
245
-			'oform' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.oform',
246
-			'docxf' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf',
247
-		];
248
-
249
-		return $this->updateMimetypes($updatedMimetypes);
250
-	}
251
-
252
-	/**
253
-	 * @throws Exception
254
-	 * @since 26.0.0.1
255
-	 */
256
-	private function introduceAsciidocType(): IResult|int|null {
257
-		$updatedMimetypes = [
258
-			'adoc' => 'text/asciidoc',
259
-			'asciidoc' => 'text/asciidoc',
260
-		];
261
-
262
-		return $this->updateMimetypes($updatedMimetypes);
263
-	}
264
-
265
-	/**
266
-	 * @throws Exception
267
-	 * @since 28.0.0.5
268
-	 */
269
-	private function introduceEnhancedMetafileFormatType(): IResult|int|null {
270
-		$updatedMimetypes = [
271
-			'emf' => 'image/emf',
272
-		];
273
-
274
-		return $this->updateMimetypes($updatedMimetypes);
275
-	}
276
-
277
-	/**
278
-	 * @throws Exception
279
-	 * @since 29.0.0.2
280
-	 */
281
-	private function introduceEmlAndMsgFormatType(): IResult|int|null {
282
-		$updatedMimetypes = [
283
-			'eml' => 'message/rfc822',
284
-			'msg' => 'application/vnd.ms-outlook',
285
-		];
286
-
287
-		return $this->updateMimetypes($updatedMimetypes);
288
-	}
289
-
290
-	/**
291
-	 * @throws Exception
292
-	 * @since 29.0.0.6
293
-	 */
294
-	private function introduceAacAudioType(): IResult|int|null {
295
-		$updatedMimetypes = [
296
-			'aac' => 'audio/aac',
297
-		];
298
-
299
-		return $this->updateMimetypes($updatedMimetypes);
300
-	}
301
-
302
-	/**
303
-	 * @throws Exception
304
-	 * @since 29.0.10
305
-	 */
306
-	private function introduceReStructuredTextFormatType(): IResult|int|null {
307
-		$updatedMimetypes = [
308
-			'rst' => 'text/x-rst',
309
-		];
310
-
311
-		return $this->updateMimetypes($updatedMimetypes);
312
-	}
313
-
314
-	/**
315
-	 * @throws Exception
316
-	 * @since 30.0.0
317
-	 */
318
-	private function introduceExcalidrawType(): IResult|int|null {
319
-		$updatedMimetypes = [
320
-			'excalidraw' => 'application/vnd.excalidraw+json',
321
-		];
322
-
323
-		return $this->updateMimetypes($updatedMimetypes);
324
-	}
325
-
326
-
327
-	/**
328
-	 * @throws Exception
329
-	 * @since 31.0.0
330
-	 */
331
-	private function introduceZstType(): IResult|int|null {
332
-		$updatedMimetypes = [
333
-			'zst' => 'application/zstd',
334
-			'nfo' => 'text/x-nfo',
335
-		];
336
-
337
-		return $this->updateMimetypes($updatedMimetypes);
338
-	}
339
-
340
-	/**
341
-	 * @throws Exception
342
-	 * @since 32.0.0
343
-	 */
344
-	private function introduceMusicxmlType(): IResult|int|null {
345
-		$updatedMimetypes = [
346
-			'mxl' => 'application/vnd.recordare.musicxml',
347
-			'musicxml' => 'application/vnd.recordare.musicxml+xml',
348
-		];
349
-
350
-		return $this->updateMimetypes($updatedMimetypes);
351
-	}
352
-
353
-	/**
354
-	 * @throws Exception
355
-	 * @since 32.0.0
356
-	 */
357
-	private function introduceTextType(): IResult|int|null {
358
-		$updatedMimetypes = [
359
-			'text' => 'text/plain',
360
-		];
361
-
362
-		return $this->updateMimetypes($updatedMimetypes);
363
-	}
364
-
365
-
366
-
367
-	/**
368
-	 * Check if there are any migrations available
369
-	 *
370
-	 * @throws Exception
371
-	 */
372
-	public function migrationsAvailable(): bool {
373
-		$this->dryRun = true;
374
-		$this->run(new NullOutput());
375
-		$this->dryRun = false;
376
-		return $this->changeCount > 0;
377
-	}
378
-
379
-	/**
380
-	 * Get the current mimetype version
381
-	 */
382
-	private function getMimeTypeVersion(): string {
383
-		$serverVersion = $this->config->getSystemValueString('version', '0.0.0');
384
-		// 29.0.0.10 is the last version with a mimetype migration before it was moved to a separate version number
385
-		if (version_compare($serverVersion, '29.0.0.10', '>')) {
386
-			return $this->appConfig->getValueString('files', 'mimetype_version', '29.0.0.10');
387
-		}
388
-
389
-		return $serverVersion;
390
-	}
391
-
392
-	/**
393
-	 * Fix mime types
394
-	 *
395
-	 * @throws Exception
396
-	 */
397
-	public function run(IOutput $out): void {
398
-		$serverVersion = $this->config->getSystemValueString('version', '0.0.0');
399
-		$mimeTypeVersion = $this->getMimeTypeVersion();
400
-
401
-		// NOTE TO DEVELOPERS: when adding new mime types, please make sure to
402
-		// add a version comparison to avoid doing it every time
403
-		// PLEASE ALSO KEEP THE LIST SORTED BY VERSION NUMBER
404
-
405
-		if (version_compare($mimeTypeVersion, '12.0.0.14', '<') && $this->introduceImageTypes()) {
406
-			$out->info('Fixed image mime types');
407
-		}
408
-
409
-		if (version_compare($mimeTypeVersion, '12.0.0.13', '<') && $this->introduceWindowsProgramTypes()) {
410
-			$out->info('Fixed windows program mime types');
411
-		}
412
-
413
-		if (version_compare($mimeTypeVersion, '13.0.0.0', '<') && $this->introduceLocationTypes()) {
414
-			$out->info('Fixed geospatial mime types');
415
-		}
416
-
417
-		if (version_compare($mimeTypeVersion, '13.0.0.3', '<') && $this->introduceInternetShortcutTypes()) {
418
-			$out->info('Fixed internet-shortcut mime types');
419
-		}
420
-
421
-		if (version_compare($mimeTypeVersion, '13.0.0.6', '<') && $this->introduceStreamingTypes()) {
422
-			$out->info('Fixed streaming mime types');
423
-		}
424
-
425
-		if (version_compare($mimeTypeVersion, '14.0.0.8', '<') && $this->introduceVisioTypes()) {
426
-			$out->info('Fixed visio mime types');
427
-		}
428
-
429
-		if (version_compare($mimeTypeVersion, '14.0.0.10', '<') && $this->introduceComicbookTypes()) {
430
-			$out->info('Fixed comicbook mime types');
431
-		}
432
-
433
-		if (version_compare($mimeTypeVersion, '20.0.0.5', '<') && $this->introduceOpenDocumentTemplates()) {
434
-			$out->info('Fixed OpenDocument template mime types');
435
-		}
436
-
437
-		if (version_compare($mimeTypeVersion, '21.0.0.7', '<') && $this->introduceOrgModeType()) {
438
-			$out->info('Fixed orgmode mime types');
439
-		}
440
-
441
-		if (version_compare($mimeTypeVersion, '23.0.0.2', '<') && $this->introduceFlatOpenDocumentType()) {
442
-			$out->info('Fixed Flat OpenDocument mime types');
443
-		}
444
-
445
-		if (version_compare($mimeTypeVersion, '25.0.0.2', '<') && $this->introduceOnlyofficeFormType()) {
446
-			$out->info('Fixed ONLYOFFICE Forms OpenXML mime types');
447
-		}
448
-
449
-		if (version_compare($mimeTypeVersion, '26.0.0.1', '<') && $this->introduceAsciidocType()) {
450
-			$out->info('Fixed AsciiDoc mime types');
451
-		}
452
-
453
-		if (version_compare($mimeTypeVersion, '28.0.0.5', '<') && $this->introduceEnhancedMetafileFormatType()) {
454
-			$out->info('Fixed Enhanced Metafile Format mime types');
455
-		}
456
-
457
-		if (version_compare($mimeTypeVersion, '29.0.0.2', '<') && $this->introduceEmlAndMsgFormatType()) {
458
-			$out->info('Fixed eml and msg mime type');
459
-		}
460
-
461
-		if (version_compare($mimeTypeVersion, '29.0.0.6', '<') && $this->introduceAacAudioType()) {
462
-			$out->info('Fixed aac mime type');
463
-		}
464
-
465
-		if (version_compare($mimeTypeVersion, '29.0.0.10', '<') && $this->introduceReStructuredTextFormatType()) {
466
-			$out->info('Fixed ReStructured Text mime type');
467
-		}
468
-
469
-		if (version_compare($mimeTypeVersion, '30.0.0.0', '<') && $this->introduceExcalidrawType()) {
470
-			$out->info('Fixed Excalidraw mime type');
471
-		}
472
-
473
-		if (version_compare($mimeTypeVersion, '31.0.0.0', '<') && $this->introduceZstType()) {
474
-			$out->info('Fixed zst mime type');
475
-		}
476
-
477
-		if (version_compare($mimeTypeVersion, '32.0.0.0', '<') && $this->introduceMusicxmlType()) {
478
-			$out->info('Fixed musicxml mime type');
479
-		}
480
-
481
-		if (version_compare($mimeTypeVersion, '32.0.0.0', '<') && $this->introduceTextType()) {
482
-			$out->info('Fixed text mime type');
483
-		}
484
-
485
-		if (!$this->dryRun) {
486
-			$this->appConfig->setValueString('files', 'mimetype_version', $serverVersion);
487
-		}
488
-	}
20
+    private bool $dryRun = false;
21
+    private int $changeCount = 0;
22
+
23
+    /** @var int */
24
+    protected int $folderMimeTypeId;
25
+
26
+    public function __construct(
27
+        protected IConfig $config,
28
+        protected IAppConfig $appConfig,
29
+        protected IDBConnection $connection,
30
+    ) {
31
+    }
32
+
33
+    public function getName(): string {
34
+        return 'Repair mime types';
35
+    }
36
+
37
+    /**
38
+     * @throws Exception
39
+     */
40
+    private function updateMimetypes($updatedMimetypes): IResult|int|null {
41
+        if ($this->dryRun) {
42
+            $this->changeCount += count($updatedMimetypes);
43
+            return null;
44
+        }
45
+
46
+        $query = $this->connection->getQueryBuilder();
47
+        $query->select('id')
48
+            ->from('mimetypes')
49
+            ->where($query->expr()->eq('mimetype', $query->createParameter('mimetype'), IQueryBuilder::PARAM_INT));
50
+        $insert = $this->connection->getQueryBuilder();
51
+        $insert->insert('mimetypes')
52
+            ->setValue('mimetype', $insert->createParameter('mimetype'));
53
+
54
+        if (empty($this->folderMimeTypeId)) {
55
+            $query->setParameter('mimetype', 'httpd/unix-directory');
56
+            $result = $query->execute();
57
+            $this->folderMimeTypeId = (int)$result->fetchOne();
58
+            $result->closeCursor();
59
+        }
60
+
61
+        $update = $this->connection->getQueryBuilder();
62
+        $update->update('filecache')
63
+            ->runAcrossAllShards()
64
+            ->set('mimetype', $update->createParameter('mimetype'))
65
+            ->where($update->expr()->neq('mimetype', $update->createParameter('mimetype'), IQueryBuilder::PARAM_INT))
66
+            ->andWhere($update->expr()->neq('mimetype', $update->createParameter('folder'), IQueryBuilder::PARAM_INT))
67
+            ->andWhere($update->expr()->iLike('name', $update->createParameter('name')))
68
+            ->setParameter('folder', $this->folderMimeTypeId);
69
+
70
+        $count = 0;
71
+        foreach ($updatedMimetypes as $extension => $mimetype) {
72
+            // get target mimetype id
73
+            $query->setParameter('mimetype', $mimetype);
74
+            $result = $query->execute();
75
+            $mimetypeId = (int)$result->fetchOne();
76
+            $result->closeCursor();
77
+
78
+            if (!$mimetypeId) {
79
+                // insert mimetype
80
+                $insert->setParameter('mimetype', $mimetype);
81
+                $insert->execute();
82
+                $mimetypeId = $insert->getLastInsertId();
83
+            }
84
+
85
+            // change mimetype for files with x extension
86
+            $update->setParameter('mimetype', $mimetypeId)
87
+                ->setParameter('name', '%' . $this->connection->escapeLikeParameter('.' . $extension));
88
+            $count += $update->execute();
89
+        }
90
+
91
+        return $count;
92
+    }
93
+
94
+    /**
95
+     * @throws Exception
96
+     * @since 12.0.0.14
97
+     */
98
+    private function introduceImageTypes(): IResult|int|null {
99
+        $updatedMimetypes = [
100
+            'jp2' => 'image/jp2',
101
+            'webp' => 'image/webp',
102
+        ];
103
+
104
+        return $this->updateMimetypes($updatedMimetypes);
105
+    }
106
+
107
+    /**
108
+     * @throws Exception
109
+     * @since 12.0.0.13
110
+     */
111
+    private function introduceWindowsProgramTypes(): IResult|int|null {
112
+        $updatedMimetypes = [
113
+            'htaccess' => 'text/plain',
114
+            'bat' => 'application/x-msdos-program',
115
+            'cmd' => 'application/cmd',
116
+        ];
117
+
118
+        return $this->updateMimetypes($updatedMimetypes);
119
+    }
120
+
121
+    /**
122
+     * @throws Exception
123
+     * @since 13.0.0.0
124
+     */
125
+    private function introduceLocationTypes(): IResult|int|null {
126
+        $updatedMimetypes = [
127
+            'gpx' => 'application/gpx+xml',
128
+            'kml' => 'application/vnd.google-earth.kml+xml',
129
+            'kmz' => 'application/vnd.google-earth.kmz',
130
+            'tcx' => 'application/vnd.garmin.tcx+xml',
131
+        ];
132
+
133
+        return $this->updateMimetypes($updatedMimetypes);
134
+    }
135
+
136
+    /**
137
+     * @throws Exception
138
+     * @since 13.0.0.3
139
+     */
140
+    private function introduceInternetShortcutTypes(): IResult|int|null {
141
+        $updatedMimetypes = [
142
+            'url' => 'application/internet-shortcut',
143
+            'webloc' => 'application/internet-shortcut'
144
+        ];
145
+
146
+        return $this->updateMimetypes($updatedMimetypes);
147
+    }
148
+
149
+    /**
150
+     * @throws Exception
151
+     * @since 13.0.0.6
152
+     */
153
+    private function introduceStreamingTypes(): IResult|int|null {
154
+        $updatedMimetypes = [
155
+            'm3u' => 'audio/mpegurl',
156
+            'm3u8' => 'audio/mpegurl',
157
+            'pls' => 'audio/x-scpls'
158
+        ];
159
+
160
+        return $this->updateMimetypes($updatedMimetypes);
161
+    }
162
+
163
+    /**
164
+     * @throws Exception
165
+     * @since 14.0.0.8
166
+     */
167
+    private function introduceVisioTypes(): IResult|int|null {
168
+        $updatedMimetypes = [
169
+            'vsdm' => 'application/vnd.visio',
170
+            'vsdx' => 'application/vnd.visio',
171
+            'vssm' => 'application/vnd.visio',
172
+            'vssx' => 'application/vnd.visio',
173
+            'vstm' => 'application/vnd.visio',
174
+            'vstx' => 'application/vnd.visio',
175
+        ];
176
+
177
+        return $this->updateMimetypes($updatedMimetypes);
178
+    }
179
+
180
+    /**
181
+     * @throws Exception
182
+     * @since 14.0.0.10
183
+     */
184
+    private function introduceComicbookTypes(): IResult|int|null {
185
+        $updatedMimetypes = [
186
+            'cb7' => 'application/comicbook+7z',
187
+            'cba' => 'application/comicbook+ace',
188
+            'cbr' => 'application/comicbook+rar',
189
+            'cbt' => 'application/comicbook+tar',
190
+            'cbtc' => 'application/comicbook+truecrypt',
191
+            'cbz' => 'application/comicbook+zip',
192
+        ];
193
+
194
+        return $this->updateMimetypes($updatedMimetypes);
195
+    }
196
+
197
+    /**
198
+     * @throws Exception
199
+     * @since 20.0.0.5
200
+     */
201
+    private function introduceOpenDocumentTemplates(): IResult|int|null {
202
+        $updatedMimetypes = [
203
+            'ott' => 'application/vnd.oasis.opendocument.text-template',
204
+            'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
205
+            'otp' => 'application/vnd.oasis.opendocument.presentation-template',
206
+            'otg' => 'application/vnd.oasis.opendocument.graphics-template',
207
+        ];
208
+
209
+        return $this->updateMimetypes($updatedMimetypes);
210
+    }
211
+
212
+    /**
213
+     * @throws Exception
214
+     * @since 21.0.0.7
215
+     */
216
+    private function introduceOrgModeType(): IResult|int|null {
217
+        $updatedMimetypes = [
218
+            'org' => 'text/org'
219
+        ];
220
+
221
+        return $this->updateMimetypes($updatedMimetypes);
222
+    }
223
+
224
+    /**
225
+     * @throws Exception
226
+     * @since 23.0.0.2
227
+     */
228
+    private function introduceFlatOpenDocumentType(): IResult|int|null {
229
+        $updatedMimetypes = [
230
+            'fodt' => 'application/vnd.oasis.opendocument.text-flat-xml',
231
+            'fods' => 'application/vnd.oasis.opendocument.spreadsheet-flat-xml',
232
+            'fodg' => 'application/vnd.oasis.opendocument.graphics-flat-xml',
233
+            'fodp' => 'application/vnd.oasis.opendocument.presentation-flat-xml',
234
+        ];
235
+
236
+        return $this->updateMimetypes($updatedMimetypes);
237
+    }
238
+
239
+    /**
240
+     * @throws Exception
241
+     * @since 25.0.0.2
242
+     */
243
+    private function introduceOnlyofficeFormType(): IResult|int|null {
244
+        $updatedMimetypes = [
245
+            'oform' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.oform',
246
+            'docxf' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf',
247
+        ];
248
+
249
+        return $this->updateMimetypes($updatedMimetypes);
250
+    }
251
+
252
+    /**
253
+     * @throws Exception
254
+     * @since 26.0.0.1
255
+     */
256
+    private function introduceAsciidocType(): IResult|int|null {
257
+        $updatedMimetypes = [
258
+            'adoc' => 'text/asciidoc',
259
+            'asciidoc' => 'text/asciidoc',
260
+        ];
261
+
262
+        return $this->updateMimetypes($updatedMimetypes);
263
+    }
264
+
265
+    /**
266
+     * @throws Exception
267
+     * @since 28.0.0.5
268
+     */
269
+    private function introduceEnhancedMetafileFormatType(): IResult|int|null {
270
+        $updatedMimetypes = [
271
+            'emf' => 'image/emf',
272
+        ];
273
+
274
+        return $this->updateMimetypes($updatedMimetypes);
275
+    }
276
+
277
+    /**
278
+     * @throws Exception
279
+     * @since 29.0.0.2
280
+     */
281
+    private function introduceEmlAndMsgFormatType(): IResult|int|null {
282
+        $updatedMimetypes = [
283
+            'eml' => 'message/rfc822',
284
+            'msg' => 'application/vnd.ms-outlook',
285
+        ];
286
+
287
+        return $this->updateMimetypes($updatedMimetypes);
288
+    }
289
+
290
+    /**
291
+     * @throws Exception
292
+     * @since 29.0.0.6
293
+     */
294
+    private function introduceAacAudioType(): IResult|int|null {
295
+        $updatedMimetypes = [
296
+            'aac' => 'audio/aac',
297
+        ];
298
+
299
+        return $this->updateMimetypes($updatedMimetypes);
300
+    }
301
+
302
+    /**
303
+     * @throws Exception
304
+     * @since 29.0.10
305
+     */
306
+    private function introduceReStructuredTextFormatType(): IResult|int|null {
307
+        $updatedMimetypes = [
308
+            'rst' => 'text/x-rst',
309
+        ];
310
+
311
+        return $this->updateMimetypes($updatedMimetypes);
312
+    }
313
+
314
+    /**
315
+     * @throws Exception
316
+     * @since 30.0.0
317
+     */
318
+    private function introduceExcalidrawType(): IResult|int|null {
319
+        $updatedMimetypes = [
320
+            'excalidraw' => 'application/vnd.excalidraw+json',
321
+        ];
322
+
323
+        return $this->updateMimetypes($updatedMimetypes);
324
+    }
325
+
326
+
327
+    /**
328
+     * @throws Exception
329
+     * @since 31.0.0
330
+     */
331
+    private function introduceZstType(): IResult|int|null {
332
+        $updatedMimetypes = [
333
+            'zst' => 'application/zstd',
334
+            'nfo' => 'text/x-nfo',
335
+        ];
336
+
337
+        return $this->updateMimetypes($updatedMimetypes);
338
+    }
339
+
340
+    /**
341
+     * @throws Exception
342
+     * @since 32.0.0
343
+     */
344
+    private function introduceMusicxmlType(): IResult|int|null {
345
+        $updatedMimetypes = [
346
+            'mxl' => 'application/vnd.recordare.musicxml',
347
+            'musicxml' => 'application/vnd.recordare.musicxml+xml',
348
+        ];
349
+
350
+        return $this->updateMimetypes($updatedMimetypes);
351
+    }
352
+
353
+    /**
354
+     * @throws Exception
355
+     * @since 32.0.0
356
+     */
357
+    private function introduceTextType(): IResult|int|null {
358
+        $updatedMimetypes = [
359
+            'text' => 'text/plain',
360
+        ];
361
+
362
+        return $this->updateMimetypes($updatedMimetypes);
363
+    }
364
+
365
+
366
+
367
+    /**
368
+     * Check if there are any migrations available
369
+     *
370
+     * @throws Exception
371
+     */
372
+    public function migrationsAvailable(): bool {
373
+        $this->dryRun = true;
374
+        $this->run(new NullOutput());
375
+        $this->dryRun = false;
376
+        return $this->changeCount > 0;
377
+    }
378
+
379
+    /**
380
+     * Get the current mimetype version
381
+     */
382
+    private function getMimeTypeVersion(): string {
383
+        $serverVersion = $this->config->getSystemValueString('version', '0.0.0');
384
+        // 29.0.0.10 is the last version with a mimetype migration before it was moved to a separate version number
385
+        if (version_compare($serverVersion, '29.0.0.10', '>')) {
386
+            return $this->appConfig->getValueString('files', 'mimetype_version', '29.0.0.10');
387
+        }
388
+
389
+        return $serverVersion;
390
+    }
391
+
392
+    /**
393
+     * Fix mime types
394
+     *
395
+     * @throws Exception
396
+     */
397
+    public function run(IOutput $out): void {
398
+        $serverVersion = $this->config->getSystemValueString('version', '0.0.0');
399
+        $mimeTypeVersion = $this->getMimeTypeVersion();
400
+
401
+        // NOTE TO DEVELOPERS: when adding new mime types, please make sure to
402
+        // add a version comparison to avoid doing it every time
403
+        // PLEASE ALSO KEEP THE LIST SORTED BY VERSION NUMBER
404
+
405
+        if (version_compare($mimeTypeVersion, '12.0.0.14', '<') && $this->introduceImageTypes()) {
406
+            $out->info('Fixed image mime types');
407
+        }
408
+
409
+        if (version_compare($mimeTypeVersion, '12.0.0.13', '<') && $this->introduceWindowsProgramTypes()) {
410
+            $out->info('Fixed windows program mime types');
411
+        }
412
+
413
+        if (version_compare($mimeTypeVersion, '13.0.0.0', '<') && $this->introduceLocationTypes()) {
414
+            $out->info('Fixed geospatial mime types');
415
+        }
416
+
417
+        if (version_compare($mimeTypeVersion, '13.0.0.3', '<') && $this->introduceInternetShortcutTypes()) {
418
+            $out->info('Fixed internet-shortcut mime types');
419
+        }
420
+
421
+        if (version_compare($mimeTypeVersion, '13.0.0.6', '<') && $this->introduceStreamingTypes()) {
422
+            $out->info('Fixed streaming mime types');
423
+        }
424
+
425
+        if (version_compare($mimeTypeVersion, '14.0.0.8', '<') && $this->introduceVisioTypes()) {
426
+            $out->info('Fixed visio mime types');
427
+        }
428
+
429
+        if (version_compare($mimeTypeVersion, '14.0.0.10', '<') && $this->introduceComicbookTypes()) {
430
+            $out->info('Fixed comicbook mime types');
431
+        }
432
+
433
+        if (version_compare($mimeTypeVersion, '20.0.0.5', '<') && $this->introduceOpenDocumentTemplates()) {
434
+            $out->info('Fixed OpenDocument template mime types');
435
+        }
436
+
437
+        if (version_compare($mimeTypeVersion, '21.0.0.7', '<') && $this->introduceOrgModeType()) {
438
+            $out->info('Fixed orgmode mime types');
439
+        }
440
+
441
+        if (version_compare($mimeTypeVersion, '23.0.0.2', '<') && $this->introduceFlatOpenDocumentType()) {
442
+            $out->info('Fixed Flat OpenDocument mime types');
443
+        }
444
+
445
+        if (version_compare($mimeTypeVersion, '25.0.0.2', '<') && $this->introduceOnlyofficeFormType()) {
446
+            $out->info('Fixed ONLYOFFICE Forms OpenXML mime types');
447
+        }
448
+
449
+        if (version_compare($mimeTypeVersion, '26.0.0.1', '<') && $this->introduceAsciidocType()) {
450
+            $out->info('Fixed AsciiDoc mime types');
451
+        }
452
+
453
+        if (version_compare($mimeTypeVersion, '28.0.0.5', '<') && $this->introduceEnhancedMetafileFormatType()) {
454
+            $out->info('Fixed Enhanced Metafile Format mime types');
455
+        }
456
+
457
+        if (version_compare($mimeTypeVersion, '29.0.0.2', '<') && $this->introduceEmlAndMsgFormatType()) {
458
+            $out->info('Fixed eml and msg mime type');
459
+        }
460
+
461
+        if (version_compare($mimeTypeVersion, '29.0.0.6', '<') && $this->introduceAacAudioType()) {
462
+            $out->info('Fixed aac mime type');
463
+        }
464
+
465
+        if (version_compare($mimeTypeVersion, '29.0.0.10', '<') && $this->introduceReStructuredTextFormatType()) {
466
+            $out->info('Fixed ReStructured Text mime type');
467
+        }
468
+
469
+        if (version_compare($mimeTypeVersion, '30.0.0.0', '<') && $this->introduceExcalidrawType()) {
470
+            $out->info('Fixed Excalidraw mime type');
471
+        }
472
+
473
+        if (version_compare($mimeTypeVersion, '31.0.0.0', '<') && $this->introduceZstType()) {
474
+            $out->info('Fixed zst mime type');
475
+        }
476
+
477
+        if (version_compare($mimeTypeVersion, '32.0.0.0', '<') && $this->introduceMusicxmlType()) {
478
+            $out->info('Fixed musicxml mime type');
479
+        }
480
+
481
+        if (version_compare($mimeTypeVersion, '32.0.0.0', '<') && $this->introduceTextType()) {
482
+            $out->info('Fixed text mime type');
483
+        }
484
+
485
+        if (!$this->dryRun) {
486
+            $this->appConfig->setValueString('files', 'mimetype_version', $serverVersion);
487
+        }
488
+    }
489 489
 }
Please login to merge, or discard this patch.
Spacing   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -37,7 +37,7 @@  discard block
 block discarded – undo
37 37
 	/**
38 38
 	 * @throws Exception
39 39
 	 */
40
-	private function updateMimetypes($updatedMimetypes): IResult|int|null {
40
+	private function updateMimetypes($updatedMimetypes): IResult | int | null {
41 41
 		if ($this->dryRun) {
42 42
 			$this->changeCount += count($updatedMimetypes);
43 43
 			return null;
@@ -54,7 +54,7 @@  discard block
 block discarded – undo
54 54
 		if (empty($this->folderMimeTypeId)) {
55 55
 			$query->setParameter('mimetype', 'httpd/unix-directory');
56 56
 			$result = $query->execute();
57
-			$this->folderMimeTypeId = (int)$result->fetchOne();
57
+			$this->folderMimeTypeId = (int) $result->fetchOne();
58 58
 			$result->closeCursor();
59 59
 		}
60 60
 
@@ -72,7 +72,7 @@  discard block
 block discarded – undo
72 72
 			// get target mimetype id
73 73
 			$query->setParameter('mimetype', $mimetype);
74 74
 			$result = $query->execute();
75
-			$mimetypeId = (int)$result->fetchOne();
75
+			$mimetypeId = (int) $result->fetchOne();
76 76
 			$result->closeCursor();
77 77
 
78 78
 			if (!$mimetypeId) {
@@ -84,7 +84,7 @@  discard block
 block discarded – undo
84 84
 
85 85
 			// change mimetype for files with x extension
86 86
 			$update->setParameter('mimetype', $mimetypeId)
87
-				->setParameter('name', '%' . $this->connection->escapeLikeParameter('.' . $extension));
87
+				->setParameter('name', '%'.$this->connection->escapeLikeParameter('.'.$extension));
88 88
 			$count += $update->execute();
89 89
 		}
90 90
 
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
 	 * @throws Exception
96 96
 	 * @since 12.0.0.14
97 97
 	 */
98
-	private function introduceImageTypes(): IResult|int|null {
98
+	private function introduceImageTypes(): IResult | int | null {
99 99
 		$updatedMimetypes = [
100 100
 			'jp2' => 'image/jp2',
101 101
 			'webp' => 'image/webp',
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
 	 * @throws Exception
109 109
 	 * @since 12.0.0.13
110 110
 	 */
111
-	private function introduceWindowsProgramTypes(): IResult|int|null {
111
+	private function introduceWindowsProgramTypes(): IResult | int | null {
112 112
 		$updatedMimetypes = [
113 113
 			'htaccess' => 'text/plain',
114 114
 			'bat' => 'application/x-msdos-program',
@@ -122,7 +122,7 @@  discard block
 block discarded – undo
122 122
 	 * @throws Exception
123 123
 	 * @since 13.0.0.0
124 124
 	 */
125
-	private function introduceLocationTypes(): IResult|int|null {
125
+	private function introduceLocationTypes(): IResult | int | null {
126 126
 		$updatedMimetypes = [
127 127
 			'gpx' => 'application/gpx+xml',
128 128
 			'kml' => 'application/vnd.google-earth.kml+xml',
@@ -137,7 +137,7 @@  discard block
 block discarded – undo
137 137
 	 * @throws Exception
138 138
 	 * @since 13.0.0.3
139 139
 	 */
140
-	private function introduceInternetShortcutTypes(): IResult|int|null {
140
+	private function introduceInternetShortcutTypes(): IResult | int | null {
141 141
 		$updatedMimetypes = [
142 142
 			'url' => 'application/internet-shortcut',
143 143
 			'webloc' => 'application/internet-shortcut'
@@ -150,7 +150,7 @@  discard block
 block discarded – undo
150 150
 	 * @throws Exception
151 151
 	 * @since 13.0.0.6
152 152
 	 */
153
-	private function introduceStreamingTypes(): IResult|int|null {
153
+	private function introduceStreamingTypes(): IResult | int | null {
154 154
 		$updatedMimetypes = [
155 155
 			'm3u' => 'audio/mpegurl',
156 156
 			'm3u8' => 'audio/mpegurl',
@@ -164,7 +164,7 @@  discard block
 block discarded – undo
164 164
 	 * @throws Exception
165 165
 	 * @since 14.0.0.8
166 166
 	 */
167
-	private function introduceVisioTypes(): IResult|int|null {
167
+	private function introduceVisioTypes(): IResult | int | null {
168 168
 		$updatedMimetypes = [
169 169
 			'vsdm' => 'application/vnd.visio',
170 170
 			'vsdx' => 'application/vnd.visio',
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
 	 * @throws Exception
182 182
 	 * @since 14.0.0.10
183 183
 	 */
184
-	private function introduceComicbookTypes(): IResult|int|null {
184
+	private function introduceComicbookTypes(): IResult | int | null {
185 185
 		$updatedMimetypes = [
186 186
 			'cb7' => 'application/comicbook+7z',
187 187
 			'cba' => 'application/comicbook+ace',
@@ -198,7 +198,7 @@  discard block
 block discarded – undo
198 198
 	 * @throws Exception
199 199
 	 * @since 20.0.0.5
200 200
 	 */
201
-	private function introduceOpenDocumentTemplates(): IResult|int|null {
201
+	private function introduceOpenDocumentTemplates(): IResult | int | null {
202 202
 		$updatedMimetypes = [
203 203
 			'ott' => 'application/vnd.oasis.opendocument.text-template',
204 204
 			'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
@@ -213,7 +213,7 @@  discard block
 block discarded – undo
213 213
 	 * @throws Exception
214 214
 	 * @since 21.0.0.7
215 215
 	 */
216
-	private function introduceOrgModeType(): IResult|int|null {
216
+	private function introduceOrgModeType(): IResult | int | null {
217 217
 		$updatedMimetypes = [
218 218
 			'org' => 'text/org'
219 219
 		];
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
 	 * @throws Exception
226 226
 	 * @since 23.0.0.2
227 227
 	 */
228
-	private function introduceFlatOpenDocumentType(): IResult|int|null {
228
+	private function introduceFlatOpenDocumentType(): IResult | int | null {
229 229
 		$updatedMimetypes = [
230 230
 			'fodt' => 'application/vnd.oasis.opendocument.text-flat-xml',
231 231
 			'fods' => 'application/vnd.oasis.opendocument.spreadsheet-flat-xml',
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
 	 * @throws Exception
241 241
 	 * @since 25.0.0.2
242 242
 	 */
243
-	private function introduceOnlyofficeFormType(): IResult|int|null {
243
+	private function introduceOnlyofficeFormType(): IResult | int | null {
244 244
 		$updatedMimetypes = [
245 245
 			'oform' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.oform',
246 246
 			'docxf' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf',
@@ -253,7 +253,7 @@  discard block
 block discarded – undo
253 253
 	 * @throws Exception
254 254
 	 * @since 26.0.0.1
255 255
 	 */
256
-	private function introduceAsciidocType(): IResult|int|null {
256
+	private function introduceAsciidocType(): IResult | int | null {
257 257
 		$updatedMimetypes = [
258 258
 			'adoc' => 'text/asciidoc',
259 259
 			'asciidoc' => 'text/asciidoc',
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
 	 * @throws Exception
267 267
 	 * @since 28.0.0.5
268 268
 	 */
269
-	private function introduceEnhancedMetafileFormatType(): IResult|int|null {
269
+	private function introduceEnhancedMetafileFormatType(): IResult | int | null {
270 270
 		$updatedMimetypes = [
271 271
 			'emf' => 'image/emf',
272 272
 		];
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
 	 * @throws Exception
279 279
 	 * @since 29.0.0.2
280 280
 	 */
281
-	private function introduceEmlAndMsgFormatType(): IResult|int|null {
281
+	private function introduceEmlAndMsgFormatType(): IResult | int | null {
282 282
 		$updatedMimetypes = [
283 283
 			'eml' => 'message/rfc822',
284 284
 			'msg' => 'application/vnd.ms-outlook',
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
 	 * @throws Exception
292 292
 	 * @since 29.0.0.6
293 293
 	 */
294
-	private function introduceAacAudioType(): IResult|int|null {
294
+	private function introduceAacAudioType(): IResult | int | null {
295 295
 		$updatedMimetypes = [
296 296
 			'aac' => 'audio/aac',
297 297
 		];
@@ -303,7 +303,7 @@  discard block
 block discarded – undo
303 303
 	 * @throws Exception
304 304
 	 * @since 29.0.10
305 305
 	 */
306
-	private function introduceReStructuredTextFormatType(): IResult|int|null {
306
+	private function introduceReStructuredTextFormatType(): IResult | int | null {
307 307
 		$updatedMimetypes = [
308 308
 			'rst' => 'text/x-rst',
309 309
 		];
@@ -315,7 +315,7 @@  discard block
 block discarded – undo
315 315
 	 * @throws Exception
316 316
 	 * @since 30.0.0
317 317
 	 */
318
-	private function introduceExcalidrawType(): IResult|int|null {
318
+	private function introduceExcalidrawType(): IResult | int | null {
319 319
 		$updatedMimetypes = [
320 320
 			'excalidraw' => 'application/vnd.excalidraw+json',
321 321
 		];
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
 	 * @throws Exception
329 329
 	 * @since 31.0.0
330 330
 	 */
331
-	private function introduceZstType(): IResult|int|null {
331
+	private function introduceZstType(): IResult | int | null {
332 332
 		$updatedMimetypes = [
333 333
 			'zst' => 'application/zstd',
334 334
 			'nfo' => 'text/x-nfo',
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
 	 * @throws Exception
342 342
 	 * @since 32.0.0
343 343
 	 */
344
-	private function introduceMusicxmlType(): IResult|int|null {
344
+	private function introduceMusicxmlType(): IResult | int | null {
345 345
 		$updatedMimetypes = [
346 346
 			'mxl' => 'application/vnd.recordare.musicxml',
347 347
 			'musicxml' => 'application/vnd.recordare.musicxml+xml',
@@ -354,7 +354,7 @@  discard block
 block discarded – undo
354 354
 	 * @throws Exception
355 355
 	 * @since 32.0.0
356 356
 	 */
357
-	private function introduceTextType(): IResult|int|null {
357
+	private function introduceTextType(): IResult | int | null {
358 358
 		$updatedMimetypes = [
359 359
 			'text' => 'text/plain',
360 360
 		];
Please login to merge, or discard this patch.