You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RepairMimeTypes.php 8.3KB

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