Passed
Push — master ( d37034...2bedfb )
by Julius
17:58 queued 10s
created

RepairMimeTypes::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Christoph Wurst <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Olivier Paroz <[email protected]>
10
 * @author Rello <[email protected]>
11
 * @author Roeland Jago Douma <[email protected]>
12
 * @author Stefan Weil <[email protected]>
13
 * @author Thomas Ebert <[email protected]>
14
 * @author Thomas Müller <[email protected]>
15
 * @author Victor Dubiniuk <[email protected]>
16
 * @author Vincent Petry <[email protected]>
17
 *
18
 * @license AGPL-3.0
19
 *
20
 * This code is free software: you can redistribute it and/or modify
21
 * it under the terms of the GNU Affero General Public License, version 3,
22
 * as published by the Free Software Foundation.
23
 *
24
 * This program is distributed in the hope that it will be useful,
25
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
 * GNU Affero General Public License for more details.
28
 *
29
 * You should have received a copy of the GNU Affero General Public License, version 3,
30
 * along with this program. If not, see <http://www.gnu.org/licenses/>
31
 *
32
 */
33
34
namespace OC\Repair;
35
36
use OCP\DB\QueryBuilder\IQueryBuilder;
37
use OCP\IConfig;
38
use OCP\IDBConnection;
39
use OCP\Migration\IOutput;
40
use OCP\Migration\IRepairStep;
41
42
class RepairMimeTypes implements IRepairStep {
43
	/** @var IConfig */
44
	protected $config;
45
	/** @var IDBConnection */
46
	protected $connection;
47
48
	/** @var int */
49
	protected $folderMimeTypeId;
50
51
	public function __construct(IConfig $config,
52
								IDBConnection $connection) {
53
		$this->config = $config;
54
		$this->connection = $connection;
55
	}
56
57
	public function getName() {
58
		return 'Repair mime types';
59
	}
60
61
	private function updateMimetypes($updatedMimetypes) {
62
		$query = $this->connection->getQueryBuilder();
63
		$query->select('id')
64
			->from('mimetypes')
65
			->where($query->expr()->eq('mimetype', $query->createParameter('mimetype'), IQueryBuilder::PARAM_INT));
66
		$insert = $this->connection->getQueryBuilder();
67
		$insert->insert('mimetypes')
68
			->setValue('mimetype', $insert->createParameter('mimetype'));
69
70
		if (empty($this->folderMimeTypeId)) {
71
			$query->setParameter('mimetype', 'httpd/unix-directory');
72
			$result = $query->execute();
73
			$this->folderMimeTypeId = (int)$result->fetchColumn();
74
			$result->closeCursor();
75
		}
76
77
		$update = $this->connection->getQueryBuilder();
78
		$update->update('filecache')
79
			->set('mimetype', $update->createParameter('mimetype'))
80
			->where($update->expr()->neq('mimetype', $update->createParameter('mimetype'), IQueryBuilder::PARAM_INT))
81
			->andWhere($update->expr()->neq('mimetype', $update->createParameter('folder'), IQueryBuilder::PARAM_INT))
82
			->andWhere($update->expr()->iLike('name', $update->createParameter('name')))
83
			->setParameter('folder', $this->folderMimeTypeId);
84
85
		$count = 0;
86
		foreach ($updatedMimetypes as $extension => $mimetype) {
87
			// get target mimetype id
88
			$query->setParameter('mimetype', $mimetype);
89
			$result = $query->execute();
90
			$mimetypeId = (int)$result->fetchColumn();
91
			$result->closeCursor();
92
93
			if (!$mimetypeId) {
94
				// insert mimetype
95
				$insert->setParameter('mimetype', $mimetype);
96
				$insert->execute();
97
				$mimetypeId = $insert->getLastInsertId();
98
			}
99
100
			// change mimetype for files with x extension
101
			$update->setParameter('mimetype', $mimetypeId)
102
				->setParameter('name', '%' . $this->connection->escapeLikeParameter('.' . $extension));
103
			$count += $update->execute();
104
		}
105
106
		return $count;
107
	}
108
109
	private function introduceImageTypes() {
110
		$updatedMimetypes = [
111
			'jp2' => 'image/jp2',
112
			'webp' => 'image/webp',
113
		];
114
115
		return $this->updateMimetypes($updatedMimetypes);
116
	}
117
118
	private function introduceWindowsProgramTypes() {
119
		$updatedMimetypes = [
120
			'htaccess' => 'text/plain',
121
			'bat' => 'application/x-msdos-program',
122
			'cmd' => 'application/cmd',
123
		];
124
125
		return $this->updateMimetypes($updatedMimetypes);
126
	}
127
128
	private function introduceLocationTypes() {
129
		$updatedMimetypes = [
130
			'gpx' => 'application/gpx+xml',
131
			'kml' => 'application/vnd.google-earth.kml+xml',
132
			'kmz' => 'application/vnd.google-earth.kmz',
133
			'tcx' => 'application/vnd.garmin.tcx+xml',
134
		];
135
136
		return $this->updateMimetypes($updatedMimetypes);
137
	}
138
139
	private function introduceInternetShortcutTypes() {
140
		$updatedMimetypes = [
141
			'url' => 'application/internet-shortcut',
142
			'webloc' => 'application/internet-shortcut'
143
		];
144
145
		return $this->updateMimetypes($updatedMimetypes);
146
	}
147
148
	private function introduceStreamingTypes() {
149
		$updatedMimetypes = [
150
			'm3u' => 'audio/mpegurl',
151
			'm3u8' => 'audio/mpegurl',
152
			'pls' => 'audio/x-scpls'
153
		];
154
155
		return $this->updateMimetypes($updatedMimetypes);
156
	}
157
158
	private function introduceVisioTypes() {
159
		$updatedMimetypes = [
160
			'vsdm' => 'application/vnd.visio',
161
			'vsdx' => 'application/vnd.visio',
162
			'vssm' => 'application/vnd.visio',
163
			'vssx' => 'application/vnd.visio',
164
			'vstm' => 'application/vnd.visio',
165
			'vstx' => 'application/vnd.visio',
166
		];
167
168
		return $this->updateMimetypes($updatedMimetypes);
169
	}
170
171
	private function introduceComicbookTypes() {
172
		$updatedMimetypes = [
173
			'cb7' => 'application/comicbook+7z',
174
			'cba' => 'application/comicbook+ace',
175
			'cbr' => 'application/comicbook+rar',
176
			'cbt' => 'application/comicbook+tar',
177
			'cbtc' => 'application/comicbook+truecrypt',
178
			'cbz' => 'application/comicbook+zip',
179
		];
180
181
		return $this->updateMimetypes($updatedMimetypes);
182
	}
183
184
	private function introduceOpenDocumentTemplates() {
185
		$updatedMimetypes = [
186
			'ott' => 'application/vnd.oasis.opendocument.text-template',
187
			'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
188
			'otp' => 'application/vnd.oasis.opendocument.presentation-template',
189
			'otg' => 'application/vnd.oasis.opendocument.graphics-template',
190
		];
191
192
		return $this->updateMimetypes($updatedMimetypes);
193
	}
194
195
	private function introduceOrgModeType() {
196
		$updatedMimetypes = [
197
			'org' => 'text/org'
198
		];
199
200
		return $this->updateMimetypes($updatedMimetypes);
201
	}
202
203
204
	/**
205
	 * Fix mime types
206
	 */
207
	public function run(IOutput $out) {
208
		$ocVersionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0');
209
210
		// NOTE TO DEVELOPERS: when adding new mime types, please make sure to
211
		// add a version comparison to avoid doing it every time
212
213
		if (version_compare($ocVersionFromBeforeUpdate, '12.0.0.14', '<') && $this->introduceImageTypes()) {
214
			$out->info('Fixed image mime types');
215
		}
216
217
		if (version_compare($ocVersionFromBeforeUpdate, '12.0.0.13', '<') && $this->introduceWindowsProgramTypes()) {
218
			$out->info('Fixed windows program mime types');
219
		}
220
221
		if (version_compare($ocVersionFromBeforeUpdate, '13.0.0.0', '<') && $this->introduceLocationTypes()) {
222
			$out->info('Fixed geospatial mime types');
223
		}
224
225
		if (version_compare($ocVersionFromBeforeUpdate, '13.0.0.3', '<') && $this->introduceInternetShortcutTypes()) {
226
			$out->info('Fixed internet-shortcut mime types');
227
		}
228
229
		if (version_compare($ocVersionFromBeforeUpdate, '13.0.0.6', '<') && $this->introduceStreamingTypes()) {
230
			$out->info('Fixed streaming mime types');
231
		}
232
233
		if (version_compare($ocVersionFromBeforeUpdate, '14.0.0.8', '<') && $this->introduceVisioTypes()) {
234
			$out->info('Fixed visio mime types');
235
		}
236
237
		if (version_compare($ocVersionFromBeforeUpdate, '14.0.0.10', '<') && $this->introduceComicbookTypes()) {
238
			$out->info('Fixed comicbook mime types');
239
		}
240
241
		if (version_compare($ocVersionFromBeforeUpdate, '20.0.0.5', '<') && $this->introduceOpenDocumentTemplates()) {
242
			$out->info('Fixed OpenDocument template mime types');
243
		}
244
		
245
		if (version_compare($ocVersionFromBeforeUpdate, '21.0.0.7', '<') && $this->introduceOrgModeType()) {
246
			$out->info('Fixed orgmode mime types');
247
		}
248
	}
249
}
250