repairmimetypes.php 5.76 KB
Newer Older
1
2
<?php
/**
3
4
5
6
7
8
 * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
 * Copyright (c) 2014 Jörn Dreyer jfd@owncloud.com
 * Copyright (c) 2014 Olivier Paroz owncloud@oparoz.com
 * This file is licensed under the Affero General Public License version 3 or
 * later.
 * See the COPYING-README file.
9
 */
10

11
12
13
14
15
16
17
18
19
namespace OC\Repair;

use OC\Hooks\BasicEmitter;

class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep {

	public function getName() {
		return 'Repair mime types';
	}
20

21
22
	private static function existsStmt() {
		return \OC_DB::prepare('
Vincent Petry's avatar
Vincent Petry committed
23
24
			SELECT count(`mimetype`)
			FROM   `*PREFIX*mimetypes`
25
26
			WHERE  `mimetype` = ?
		');
27
	}
28

29
30
	private static function getIdStmt() {
		return \OC_DB::prepare('
Vincent Petry's avatar
Vincent Petry committed
31
32
33
34
			SELECT `id`
			FROM   `*PREFIX*mimetypes`
			WHERE  `mimetype` = ?
		');
35
	}
Vincent Petry's avatar
Vincent Petry committed
36

37
38
	private static function insertStmt() {
		return \OC_DB::prepare('
Vincent Petry's avatar
Vincent Petry committed
39
40
41
			INSERT INTO `*PREFIX*mimetypes` ( `mimetype` )
			VALUES ( ? )
		');
42
	}
Vincent Petry's avatar
Vincent Petry committed
43

44
45
	private static function updateWrongStmt() {
		return \OC_DB::prepare('
Vincent Petry's avatar
Vincent Petry committed
46
47
48
49
50
51
52
			UPDATE `*PREFIX*filecache`
			SET `mimetype` = (
				SELECT `id`
				FROM `*PREFIX*mimetypes`
				WHERE `mimetype` = ?
			) WHERE `mimetype` = ?
		');
53
	}
54

55
56
	private static function deleteStmt() {
		return \OC_DB::prepare('
Vincent Petry's avatar
Vincent Petry committed
57
58
59
			DELETE FROM `*PREFIX*mimetypes`
			WHERE `id` = ?
		');
60
61
	}

62
63
64
65
66
67
68
	private static function updateByNameStmt() {
		return \OC_DB::prepare('
			UPDATE `*PREFIX*filecache`
			SET `mimetype` = (
				SELECT `id`
				FROM `*PREFIX*mimetypes`
				WHERE `mimetype` = ?
69
			) WHERE `name` ILIKE ?
70
71
		');
	}
72

73
	private function repairMimetypes($wrongMimetypes) {
74
		foreach ($wrongMimetypes as $wrong => $correct) {
Vincent Petry's avatar
Vincent Petry committed
75
			// do we need to remove a wrong mimetype?
76
			$result = \OC_DB::executeAudited(self::getIdStmt(), array($wrong));
Vincent Petry's avatar
Vincent Petry committed
77
78
79
80
			$wrongId = $result->fetchOne();

			if ($wrongId !== false) {
				// do we need to insert the correct mimetype?
81
				$result = \OC_DB::executeAudited(self::existsStmt(), array($correct));
Vincent Petry's avatar
Vincent Petry committed
82
83
				$exists = $result->fetchOne();

84
85
				if (!is_null($correct)) {
					if (!$exists) {
86
87
88
						// insert mimetype
						\OC_DB::executeAudited(self::insertStmt(), array($correct));
					}
Vincent Petry's avatar
Vincent Petry committed
89

90
91
92
					// change wrong mimetype to correct mimetype in filecache
					\OC_DB::executeAudited(self::updateWrongStmt(), array($correct, $wrongId));
				}
93

Vincent Petry's avatar
Vincent Petry committed
94
				// delete wrong mimetype
95
				\OC_DB::executeAudited(self::deleteStmt(), array($wrongId));
Vincent Petry's avatar
Vincent Petry committed
96
97

			}
98
		}
99
	}
100

101
	private function updateMimetypes($updatedMimetypes) {
102
103

		foreach ($updatedMimetypes as $extension => $mimetype) {
104
			$result = \OC_DB::executeAudited(self::existsStmt(), array($mimetype));
105
106
			$exists = $result->fetchOne();

107
			if (!$exists) {
108
				// insert mimetype
109
				\OC_DB::executeAudited(self::insertStmt(), array($mimetype));
110
111
112
			}

			// change mimetype for files with x extension
113
			\OC_DB::executeAudited(self::updateByNameStmt(), array($mimetype, '%.' . $extension));
114
115
116
		}
	}

117
118
119
120
121
122
	private function fixOfficeMimeTypes() {
		// update wrong mimetypes
		$wrongMimetypes = array(
			'application/mspowerpoint' => 'application/vnd.ms-powerpoint',
			'application/msexcel' => 'application/vnd.ms-excel',
		);
Normal Ra's avatar
Normal Ra committed
123

124
		self::repairMimetypes($wrongMimetypes);
Normal Ra's avatar
Normal Ra committed
125

126
127
128
129
130
		$updatedMimetypes = array(
			'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
			'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
			'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
		);
Normal Ra's avatar
Normal Ra committed
131
132


133
134
		// separate doc from docx etc
		self::updateMimetypes($updatedMimetypes);
135

136
	}
137

138
139
140
141
	private function fixApkMimeType() {
		$updatedMimetypes = array(
			'apk' => 'application/vnd.android.package-archive',
		);
Normal Ra's avatar
Normal Ra committed
142

143
144
		self::updateMimetypes($updatedMimetypes);
	}
145

146
147
148
149
150
151
152
	private function fixFontsMimeTypes() {
		// update wrong mimetypes
		$wrongMimetypes = array(
			'font' => null,
			'font/opentype' => 'application/font-sfnt',
			'application/x-font-ttf' => 'application/font-sfnt',
		);
Normal Ra's avatar
Normal Ra committed
153

154
		self::repairMimetypes($wrongMimetypes);
155

156
157
158
159
160
		$updatedMimetypes = array(
			'ttf' => 'application/font-sfnt',
			'otf' => 'application/font-sfnt',
			'pfb' => 'application/x-font',
		);
Normal Ra's avatar
Normal Ra committed
161

162
163
		self::updateMimetypes($updatedMimetypes);
	}
164

165
166
167
168
169
	private function fixPostscriptMimeType() {
		$updatedMimetypes = array(
			'eps' => 'application/postscript',
			'ps' => 'application/postscript',
		);
Normal Ra's avatar
Normal Ra committed
170

171
		self::updateMimetypes($updatedMimetypes);
Normal Ra's avatar
Normal Ra committed
172
173
	}

Olivier Paroz's avatar
Olivier Paroz committed
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	private function introduceRawMimeType() {
		$updatedMimetypes = array(
			'arw' => 'image/x-dcraw',
			'cr2' => 'image/x-dcraw',
			'dcr' => 'image/x-dcraw',
			'dng' => 'image/x-dcraw',
			'erf' => 'image/x-dcraw',
			'iiq' => 'image/x-dcraw',
			'k25' => 'image/x-dcraw',
			'kdc' => 'image/x-dcraw',
			'mef' => 'image/x-dcraw',
			'nef' => 'image/x-dcraw',
			'orf' => 'image/x-dcraw',
			'pef' => 'image/x-dcraw',
			'raf' => 'image/x-dcraw',
			'rw2' => 'image/x-dcraw',
			'srf' => 'image/x-dcraw',
			'sr2' => 'image/x-dcraw',
			'xrf' => 'image/x-dcraw',
		);

		self::updateMimetypes($updatedMimetypes);
	}

198
199
200
201
202
203
204
205
206
	private function introduce3dImagesMimeType() {
		$updatedMimetypes = array(
			'jps' => 'image/jpeg',
			'mpo' => 'image/jpeg',
		);

		self::updateMimetypes($updatedMimetypes);
	}

207
208
209
210
211
212
213
	/**
	 * Fix mime types
	 */
	public function run() {
		if ($this->fixOfficeMimeTypes()) {
			$this->emit('\OC\Repair', 'info', array('Fixed office mime types'));
		}
214

215
		if ($this->fixApkMimeType()) {
Normal Ra's avatar
Normal Ra committed
216
217
			$this->emit('\OC\Repair', 'info', array('Fixed APK mime type'));
		}
218

219
220
221
		if ($this->fixFontsMimeTypes()) {
			$this->emit('\OC\Repair', 'info', array('Fixed fonts mime types'));
		}
222

223
224
225
		if ($this->fixPostscriptMimeType()) {
			$this->emit('\OC\Repair', 'info', array('Fixed Postscript mime types'));
		}
Olivier Paroz's avatar
Olivier Paroz committed
226
227
228
229

		if ($this->introduceRawMimeType()) {
			$this->emit('\OC\Repair', 'info', array('Fixed Raw mime types'));
		}
230
231
232
233

		if ($this->introduce3dImagesMimeType()) {
			$this->emit('\OC\Repair', 'info', array('Fixed 3D images mime types'));
		}
234
	}
Olivier Paroz's avatar
Olivier Paroz committed
235
}