repairmimetypes.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <?php
  2. /**
  3. * @author Joas Schilling <nickvergessen@owncloud.com>
  4. * @author Morris Jobke <hey@morrisjobke.de>
  5. * @author Normal Ra <normalraw@gmail.com>
  6. * @author Olivier Paroz <github@oparoz.com>
  7. * @author Victor Dubiniuk <dubiniuk@owncloud.com>
  8. * @author Vincent Petry <pvince81@owncloud.com>
  9. *
  10. * @copyright Copyright (c) 2015, ownCloud, Inc.
  11. * @license AGPL-3.0
  12. *
  13. * This code is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Affero General Public License, version 3,
  15. * as published by the Free Software Foundation.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU Affero General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Affero General Public License, version 3,
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>
  24. *
  25. */
  26. namespace OC\Repair;
  27. use OC\Hooks\BasicEmitter;
  28. class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep {
  29. public function getName() {
  30. return 'Repair mime types';
  31. }
  32. private static function existsStmt() {
  33. return \OC_DB::prepare('
  34. SELECT count(`mimetype`)
  35. FROM `*PREFIX*mimetypes`
  36. WHERE `mimetype` = ?
  37. ');
  38. }
  39. private static function getIdStmt() {
  40. return \OC_DB::prepare('
  41. SELECT `id`
  42. FROM `*PREFIX*mimetypes`
  43. WHERE `mimetype` = ?
  44. ');
  45. }
  46. private static function insertStmt() {
  47. return \OC_DB::prepare('
  48. INSERT INTO `*PREFIX*mimetypes` ( `mimetype` )
  49. VALUES ( ? )
  50. ');
  51. }
  52. private static function updateWrongStmt() {
  53. return \OC_DB::prepare('
  54. UPDATE `*PREFIX*filecache`
  55. SET `mimetype` = (
  56. SELECT `id`
  57. FROM `*PREFIX*mimetypes`
  58. WHERE `mimetype` = ?
  59. ) WHERE `mimetype` = ?
  60. ');
  61. }
  62. private static function deleteStmt() {
  63. return \OC_DB::prepare('
  64. DELETE FROM `*PREFIX*mimetypes`
  65. WHERE `id` = ?
  66. ');
  67. }
  68. private static function updateByNameStmt() {
  69. return \OC_DB::prepare('
  70. UPDATE `*PREFIX*filecache`
  71. SET `mimetype` = ?
  72. WHERE `mimetype` <> ? AND `name` ILIKE ?
  73. ');
  74. }
  75. private function repairMimetypes($wrongMimetypes) {
  76. foreach ($wrongMimetypes as $wrong => $correct) {
  77. // do we need to remove a wrong mimetype?
  78. $result = \OC_DB::executeAudited(self::getIdStmt(), array($wrong));
  79. $wrongId = $result->fetchOne();
  80. if ($wrongId !== false) {
  81. // do we need to insert the correct mimetype?
  82. $result = \OC_DB::executeAudited(self::existsStmt(), array($correct));
  83. $exists = $result->fetchOne();
  84. if (!is_null($correct)) {
  85. if (!$exists) {
  86. // insert mimetype
  87. \OC_DB::executeAudited(self::insertStmt(), array($correct));
  88. }
  89. // change wrong mimetype to correct mimetype in filecache
  90. \OC_DB::executeAudited(self::updateWrongStmt(), array($correct, $wrongId));
  91. }
  92. // delete wrong mimetype
  93. \OC_DB::executeAudited(self::deleteStmt(), array($wrongId));
  94. }
  95. }
  96. }
  97. private function updateMimetypes($updatedMimetypes) {
  98. foreach ($updatedMimetypes as $extension => $mimetype) {
  99. $result = \OC_DB::executeAudited(self::existsStmt(), array($mimetype));
  100. $exists = $result->fetchOne();
  101. if (!$exists) {
  102. // insert mimetype
  103. \OC_DB::executeAudited(self::insertStmt(), array($mimetype));
  104. }
  105. // get target mimetype id
  106. $result = \OC_DB::executeAudited(self::getIdStmt(), array($mimetype));
  107. $mimetypeId = $result->fetchOne();
  108. // change mimetype for files with x extension
  109. \OC_DB::executeAudited(self::updateByNameStmt(), array($mimetypeId, $mimetypeId, '%.' . $extension));
  110. }
  111. }
  112. private function fixOfficeMimeTypes() {
  113. // update wrong mimetypes
  114. $wrongMimetypes = array(
  115. 'application/mspowerpoint' => 'application/vnd.ms-powerpoint',
  116. 'application/msexcel' => 'application/vnd.ms-excel',
  117. );
  118. self::repairMimetypes($wrongMimetypes);
  119. $updatedMimetypes = array(
  120. 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  121. 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  122. 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
  123. );
  124. // separate doc from docx etc
  125. self::updateMimetypes($updatedMimetypes);
  126. }
  127. private function fixApkMimeType() {
  128. $updatedMimetypes = array(
  129. 'apk' => 'application/vnd.android.package-archive',
  130. );
  131. self::updateMimetypes($updatedMimetypes);
  132. }
  133. private function fixFontsMimeTypes() {
  134. // update wrong mimetypes
  135. $wrongMimetypes = array(
  136. 'font' => null,
  137. 'font/opentype' => 'application/font-sfnt',
  138. 'application/x-font-ttf' => 'application/font-sfnt',
  139. );
  140. self::repairMimetypes($wrongMimetypes);
  141. $updatedMimetypes = array(
  142. 'ttf' => 'application/font-sfnt',
  143. 'otf' => 'application/font-sfnt',
  144. 'pfb' => 'application/x-font',
  145. );
  146. self::updateMimetypes($updatedMimetypes);
  147. }
  148. private function fixPostscriptMimeType() {
  149. $updatedMimetypes = array(
  150. 'eps' => 'application/postscript',
  151. 'ps' => 'application/postscript',
  152. );
  153. self::updateMimetypes($updatedMimetypes);
  154. }
  155. private function introduceRawMimeType() {
  156. $updatedMimetypes = array(
  157. 'arw' => 'image/x-dcraw',
  158. 'cr2' => 'image/x-dcraw',
  159. 'dcr' => 'image/x-dcraw',
  160. 'dng' => 'image/x-dcraw',
  161. 'erf' => 'image/x-dcraw',
  162. 'iiq' => 'image/x-dcraw',
  163. 'k25' => 'image/x-dcraw',
  164. 'kdc' => 'image/x-dcraw',
  165. 'mef' => 'image/x-dcraw',
  166. 'nef' => 'image/x-dcraw',
  167. 'orf' => 'image/x-dcraw',
  168. 'pef' => 'image/x-dcraw',
  169. 'raf' => 'image/x-dcraw',
  170. 'rw2' => 'image/x-dcraw',
  171. 'srf' => 'image/x-dcraw',
  172. 'sr2' => 'image/x-dcraw',
  173. 'xrf' => 'image/x-dcraw',
  174. );
  175. self::updateMimetypes($updatedMimetypes);
  176. }
  177. private function introduce3dImagesMimeType() {
  178. $updatedMimetypes = array(
  179. 'jps' => 'image/jpeg',
  180. 'mpo' => 'image/jpeg',
  181. );
  182. self::updateMimetypes($updatedMimetypes);
  183. }
  184. private function introduceConfMimeType() {
  185. $updatedMimetypes = array(
  186. 'conf' => 'text/plain',
  187. 'cnf' => 'text/plain',
  188. );
  189. self::updateMimetypes($updatedMimetypes);
  190. }
  191. private function introduceYamlMimeType() {
  192. $updatedMimetypes = array(
  193. 'yaml' => 'application/yaml',
  194. 'yml' => 'application/yaml',
  195. );
  196. self::updateMimetypes($updatedMimetypes);
  197. }
  198. /**
  199. * Fix mime types
  200. */
  201. public function run() {
  202. if ($this->fixOfficeMimeTypes()) {
  203. $this->emit('\OC\Repair', 'info', array('Fixed office mime types'));
  204. }
  205. if ($this->fixApkMimeType()) {
  206. $this->emit('\OC\Repair', 'info', array('Fixed APK mime type'));
  207. }
  208. if ($this->fixFontsMimeTypes()) {
  209. $this->emit('\OC\Repair', 'info', array('Fixed fonts mime types'));
  210. }
  211. if ($this->fixPostscriptMimeType()) {
  212. $this->emit('\OC\Repair', 'info', array('Fixed Postscript mime types'));
  213. }
  214. if ($this->introduceRawMimeType()) {
  215. $this->emit('\OC\Repair', 'info', array('Fixed Raw mime types'));
  216. }
  217. if ($this->introduce3dImagesMimeType()) {
  218. $this->emit('\OC\Repair', 'info', array('Fixed 3D images mime types'));
  219. }
  220. if ($this->introduceConfMimeType()) {
  221. $this->emit('\OC\Repair', 'info', array('Fixed Conf/cnf mime types'));
  222. }
  223. if ($this->introduceYamlMimeType()) {
  224. $this->emit('\OC\Repair', 'info', array('Fixed Yaml/Yml mime types'));
  225. }
  226. }
  227. }