Completed
Push — master ( f0158e...2060ff )
by Blizzz
50:16 queued 36:57
created

RepairMimeTypes::run()   C

Complexity

Conditions 9
Paths 16

Size

Total Lines 23
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 10
nc 16
nop 1
dl 0
loc 23
rs 5.8541
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Faruk Uzun <[email protected]>
6
 * @author Joas Schilling <[email protected]>
7
 * @author Morris Jobke <[email protected]>
8
 * @author Normal Ra <[email protected]>
9
 * @author Olivier Paroz <[email protected]>
10
 * @author Roeland Jago Douma <[email protected]>
11
 * @author Thomas Müller <[email protected]>
12
 * @author Victor Dubiniuk <[email protected]>
13
 * @author Vincent Petry <[email protected]>
14
 *
15
 * @license AGPL-3.0
16
 *
17
 * This code is free software: you can redistribute it and/or modify
18
 * it under the terms of the GNU Affero General Public License, version 3,
19
 * as published by the Free Software Foundation.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License, version 3,
27
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
28
 *
29
 */
30
31
namespace OC\Repair;
32
33
use OCP\Migration\IOutput;
34
use OCP\Migration\IRepairStep;
35
36
class RepairMimeTypes implements IRepairStep {
37
	/**
38
	 * @var \OCP\IConfig
39
	 */
40
	protected $config;
41
42
	/**
43
	 * @var int
44
	 */
45
	protected $folderMimeTypeId;
46
47
	/**
48
	 * @param \OCP\IConfig $config
49
	 */
50
	public function __construct($config) {
51
		$this->config = $config;
52
	}
53
54
	public function getName() {
55
		return 'Repair mime types';
56
	}
57
58
	private static function existsStmt() {
59
		return \OC_DB::prepare('
60
			SELECT count(`mimetype`)
61
			FROM   `*PREFIX*mimetypes`
62
			WHERE  `mimetype` = ?
63
		');
64
	}
65
66
	private static function getIdStmt() {
67
		return \OC_DB::prepare('
68
			SELECT `id`
69
			FROM   `*PREFIX*mimetypes`
70
			WHERE  `mimetype` = ?
71
		');
72
	}
73
74
	private static function insertStmt() {
75
		return \OC_DB::prepare('
76
			INSERT INTO `*PREFIX*mimetypes` ( `mimetype` )
77
			VALUES ( ? )
78
		');
79
	}
80
81
	private static function updateByNameStmt() {
82
		return \OC_DB::prepare('
83
			UPDATE `*PREFIX*filecache`
84
			SET `mimetype` = ?
85
			WHERE `mimetype` <> ? AND `mimetype` <> ? AND `name` ILIKE ?
86
		');
87
	}
88
89
	private function updateMimetypes($updatedMimetypes) {
90
		if (empty($this->folderMimeTypeId)) {
91
			$result = \OC_DB::executeAudited(self::getIdStmt(), array('httpd/unix-directory'));
92
			$this->folderMimeTypeId = (int)$result->fetchOne();
93
		}
94
95
		foreach ($updatedMimetypes as $extension => $mimetype) {
96
			$result = \OC_DB::executeAudited(self::existsStmt(), array($mimetype));
97
			$exists = $result->fetchOne();
98
99
			if (!$exists) {
100
				// insert mimetype
101
				\OC_DB::executeAudited(self::insertStmt(), array($mimetype));
102
			}
103
104
			// get target mimetype id
105
			$result = \OC_DB::executeAudited(self::getIdStmt(), array($mimetype));
106
			$mimetypeId = $result->fetchOne();
107
108
			// change mimetype for files with x extension
109
			\OC_DB::executeAudited(self::updateByNameStmt(), array($mimetypeId, $this->folderMimeTypeId, $mimetypeId, '%.' . $extension));
110
		}
111
	}
112
113
	private function introduceImageTypes() {
114
		$updatedMimetypes = array(
115
			'jp2' => 'image/jp2',
116
			'webp' => 'image/webp',
117
		);
118
119
		$this->updateMimetypes($updatedMimetypes);
120
	}
121
122
	private function introduceWindowsProgramTypes() {
123
		$updatedMimetypes = array(
124
			'htaccess' => 'text/plain',
125
			'bat' => 'application/x-msdos-program',
126
			'cmd' => 'application/cmd',
127
		);
128
129
		$this->updateMimetypes($updatedMimetypes);
130
	}
131
132
	private function introduceLocationTypes() {
133
		$updatedMimetypes = [
134
			'gpx' => 'application/gpx+xml',
135
			'kml' => 'application/vnd.google-earth.kml+xml',
136
			'kmz' => 'application/vnd.google-earth.kmz',
137
			'tcx' => 'application/vnd.garmin.tcx+xml',
138
		];
139
140
		$this->updateMimetypes($updatedMimetypes);
141
	}
142
143
	private function introduceInternetShortcutTypes() {
144
		$updatedMimetypes = [
145
			'url' => 'application/internet-shortcut',
146
			'webloc' => 'application/internet-shortcut'
147
		];
148
149
		$this->updateMimetypes($updatedMimetypes);
150
	}
151
152
	/**
153
	 * Fix mime types
154
	 */
155
	public function run(IOutput $out) {
156
157
		$ocVersionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0');
158
159
		// NOTE TO DEVELOPERS: when adding new mime types, please make sure to
160
		// add a version comparison to avoid doing it every time
161
162
		if (version_compare($ocVersionFromBeforeUpdate, '12.0.0.14', '<') && $this->introduceImageTypes()) {
163
			$out->info('Fixed image mime types');
164
		}
165
166
		if (version_compare($ocVersionFromBeforeUpdate, '12.0.0.13', '<') && $this->introduceWindowsProgramTypes()) {
167
			$out->info('Fixed windows program mime types');
168
		}
169
170
		if (version_compare($ocVersionFromBeforeUpdate, '13.0.0.0', '<') && $this->introduceLocationTypes()) {
171
			$out->info('Fixed geospatial mime types');
172
		}
173
174
		if (version_compare($ocVersionFromBeforeUpdate, '13.0.0.3', '<') && $this->introduceInternetShortcutTypes()) {
175
			$out->info('Fixed internet-shortcut mime types');
176
		}
177
	}
178
}
179