From c936bda0f66195f88815c147237c1e599b463d0e Mon Sep 17 00:00:00 2001
From: Dave Long <dave@longwaveconsulting.com>
Date: Sun, 18 Feb 2024 13:16:28 +0000
Subject: [PATCH] Issue #3411266 by kim.pepper, quietone, smustgrave: Convert
 file_icon_class() and file_icon_map() to a utlity class and deprecate

---
 core/modules/file/file.module                 | 157 ++--------------
 core/modules/file/src/IconMimeTypes.php       | 176 ++++++++++++++++++
 .../tests/src/Kernel/LegacyFileModuleTest.php |  18 ++
 3 files changed, 211 insertions(+), 140 deletions(-)
 create mode 100644 core/modules/file/src/IconMimeTypes.php

diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 1e94f910416a..7c862ed005d5 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -26,9 +26,10 @@
 use Drupal\Core\Url;
 use Drupal\file\Entity\File;
 use Drupal\file\FileInterface;
+use Drupal\file\IconMimeTypes;
 use Drupal\file\Upload\FormUploadedFile;
 
-// cspell:ignore abiword widthx
+// cspell:ignore widthx
 
 /**
  * Implements hook_help().
@@ -1077,7 +1078,7 @@ function template_preprocess_file_link(&$variables) {
     // Add a specific class for each and every mime type.
     'file--mime-' . strtr($mime_type, ['/' => '-', '.' => '-']),
     // Add a more general class for groups of well known MIME types.
-    'file--' . file_icon_class($mime_type),
+    'file--' . IconMimeTypes::getIconClass($mime_type),
   ];
 
   // Set file classes to the options array.
@@ -1285,23 +1286,15 @@ function template_preprocess_file_upload_help(&$variables) {
  *
  * @return string
  *   A class associated with the file.
+ *
+ * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use
+ *   \Drupal\file\IconMimeTypes::getIconClass() instead.
+ *
+ * @see https://www.drupal.org/node/3411269
  */
 function file_icon_class($mime_type) {
-  // Search for a group with the files MIME type.
-  $generic_mime = (string) file_icon_map($mime_type);
-  if (!empty($generic_mime)) {
-    return $generic_mime;
-  }
-
-  // Use generic icons for each category that provides such icons.
-  foreach (['audio', 'image', 'text', 'video'] as $category) {
-    if (str_starts_with($mime_type, $category)) {
-      return $category;
-    }
-  }
-
-  // If there's no generic icon for the type the general class.
-  return 'general';
+  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\IconMimeTypes::getIconClass() instead. See https://www.drupal.org/node/3411269', E_USER_DEPRECATED);
+  return IconMimeTypes::getIconClass($mime_type);
 }
 
 /**
@@ -1312,131 +1305,15 @@ function file_icon_class($mime_type) {
  *
  * @return string|false
  *   The generic icon MIME package expected for this file.
+ *
+ *  @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use
+ *    \Drupal\file\IconMimeTypes::getGenericMimeType() instead.
+ *
+ * @see https://www.drupal.org/node/3411269
  */
 function file_icon_map($mime_type) {
-  switch ($mime_type) {
-    // Word document types.
-    case 'application/msword':
-    case 'application/vnd.ms-word.document.macroEnabled.12':
-    case 'application/vnd.oasis.opendocument.text':
-    case 'application/vnd.oasis.opendocument.text-template':
-    case 'application/vnd.oasis.opendocument.text-master':
-    case 'application/vnd.oasis.opendocument.text-web':
-    case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
-    case 'application/vnd.stardivision.writer':
-    case 'application/vnd.sun.xml.writer':
-    case 'application/vnd.sun.xml.writer.template':
-    case 'application/vnd.sun.xml.writer.global':
-    case 'application/vnd.wordperfect':
-    case 'application/x-abiword':
-    case 'application/x-applix-word':
-    case 'application/x-kword':
-    case 'application/x-kword-crypt':
-      return 'x-office-document';
-
-    // Spreadsheet document types.
-    case 'application/vnd.ms-excel':
-    case 'application/vnd.ms-excel.sheet.macroEnabled.12':
-    case 'application/vnd.oasis.opendocument.spreadsheet':
-    case 'application/vnd.oasis.opendocument.spreadsheet-template':
-    case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
-    case 'application/vnd.stardivision.calc':
-    case 'application/vnd.sun.xml.calc':
-    case 'application/vnd.sun.xml.calc.template':
-    case 'application/vnd.lotus-1-2-3':
-    case 'application/x-applix-spreadsheet':
-    case 'application/x-gnumeric':
-    case 'application/x-kspread':
-    case 'application/x-kspread-crypt':
-      return 'x-office-spreadsheet';
-
-    // Presentation document types.
-    case 'application/vnd.ms-powerpoint':
-    case 'application/vnd.ms-powerpoint.presentation.macroEnabled.12':
-    case 'application/vnd.oasis.opendocument.presentation':
-    case 'application/vnd.oasis.opendocument.presentation-template':
-    case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
-    case 'application/vnd.stardivision.impress':
-    case 'application/vnd.sun.xml.impress':
-    case 'application/vnd.sun.xml.impress.template':
-    case 'application/x-kpresenter':
-      return 'x-office-presentation';
-
-    // Compressed archive types.
-    case 'application/zip':
-    case 'application/x-zip':
-    case 'application/stuffit':
-    case 'application/x-stuffit':
-    case 'application/x-7z-compressed':
-    case 'application/x-ace':
-    case 'application/x-arj':
-    case 'application/x-bzip':
-    case 'application/x-bzip-compressed-tar':
-    case 'application/x-compress':
-    case 'application/x-compressed-tar':
-    case 'application/x-cpio-compressed':
-    case 'application/x-deb':
-    case 'application/x-gzip':
-    case 'application/x-java-archive':
-    case 'application/x-lha':
-    case 'application/x-lhz':
-    case 'application/x-lzop':
-    case 'application/x-rar':
-    case 'application/x-rpm':
-    case 'application/x-tzo':
-    case 'application/x-tar':
-    case 'application/x-tarz':
-    case 'application/x-tgz':
-      return 'package-x-generic';
-
-    // Script file types.
-    case 'application/ecmascript':
-    case 'application/javascript':
-    case 'application/mathematica':
-    case 'application/vnd.mozilla.xul+xml':
-    case 'application/x-asp':
-    case 'application/x-awk':
-    case 'application/x-cgi':
-    case 'application/x-csh':
-    case 'application/x-m4':
-    case 'application/x-perl':
-    case 'application/x-php':
-    case 'application/x-ruby':
-    case 'application/x-shellscript':
-    case 'text/javascript':
-    case 'text/vnd.wap.wmlscript':
-    case 'text/x-emacs-lisp':
-    case 'text/x-haskell':
-    case 'text/x-literate-haskell':
-    case 'text/x-lua':
-    case 'text/x-makefile':
-    case 'text/x-matlab':
-    case 'text/x-python':
-    case 'text/x-sql':
-    case 'text/x-tcl':
-      return 'text-x-script';
-
-    // HTML aliases.
-    case 'application/xhtml+xml':
-      return 'text-html';
-
-    // Executable types.
-    case 'application/x-macbinary':
-    case 'application/x-ms-dos-executable':
-    case 'application/x-pef-executable':
-      return 'application-x-executable';
-
-    // Acrobat types
-    case 'application/pdf':
-    case 'application/x-pdf':
-    case 'applications/vnd.pdf':
-    case 'text/pdf':
-    case 'text/x-pdf':
-      return 'application-pdf';
-
-    default:
-      return FALSE;
-  }
+  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\IconMimeTypes::getGenericMimeType() instead. See https://www.drupal.org/node/3411269', E_USER_DEPRECATED);
+  return IconMimeTypes::getGenericMimeType($mime_type);
 }
 
 /**
diff --git a/core/modules/file/src/IconMimeTypes.php b/core/modules/file/src/IconMimeTypes.php
new file mode 100644
index 000000000000..982f8f45ac21
--- /dev/null
+++ b/core/modules/file/src/IconMimeTypes.php
@@ -0,0 +1,176 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\file;
+
+// cspell:ignore abiword
+
+/**
+ * A utility class for working with MIME types.
+ */
+final class IconMimeTypes {
+
+  /**
+   * Gets a class for the icon for a MIME type.
+   *
+   * @param string $mimeType
+   *   A MIME type.
+   *
+   * @return string
+   *   A class associated with the file.
+   */
+  public static function getIconClass(string $mimeType): string {
+    // Search for a group with the files MIME type.
+    $genericMime = (string) self::getGenericMimeType($mimeType);
+    if (!empty($genericMime)) {
+      return $genericMime;
+    }
+
+    // Use generic icons for each category that provides such icons.
+    foreach (['audio', 'image', 'text', 'video'] as $category) {
+      if (str_starts_with($mimeType, $category)) {
+        return $category;
+      }
+    }
+
+    // If there's no generic icon for the type the general class.
+    return 'general';
+  }
+
+  /**
+   * Determines the generic icon MIME package based on a file's MIME type.
+   *
+   * @param string $mimeType
+   *   A MIME type.
+   *
+   * @return string|false
+   *   The generic icon MIME package expected for this file.
+   */
+  public static function getGenericMimeType(string $mimeType): string | false {
+    switch ($mimeType) {
+      // Word document types.
+      case 'application/msword':
+      case 'application/vnd.ms-word.document.macroEnabled.12':
+      case 'application/vnd.oasis.opendocument.text':
+      case 'application/vnd.oasis.opendocument.text-template':
+      case 'application/vnd.oasis.opendocument.text-master':
+      case 'application/vnd.oasis.opendocument.text-web':
+      case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
+      case 'application/vnd.stardivision.writer':
+      case 'application/vnd.sun.xml.writer':
+      case 'application/vnd.sun.xml.writer.template':
+      case 'application/vnd.sun.xml.writer.global':
+      case 'application/vnd.wordperfect':
+      case 'application/x-abiword':
+      case 'application/x-applix-word':
+      case 'application/x-kword':
+      case 'application/x-kword-crypt':
+        return 'x-office-document';
+
+      // Spreadsheet document types.
+      case 'application/vnd.ms-excel':
+      case 'application/vnd.ms-excel.sheet.macroEnabled.12':
+      case 'application/vnd.oasis.opendocument.spreadsheet':
+      case 'application/vnd.oasis.opendocument.spreadsheet-template':
+      case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
+      case 'application/vnd.stardivision.calc':
+      case 'application/vnd.sun.xml.calc':
+      case 'application/vnd.sun.xml.calc.template':
+      case 'application/vnd.lotus-1-2-3':
+      case 'application/x-applix-spreadsheet':
+      case 'application/x-gnumeric':
+      case 'application/x-kspread':
+      case 'application/x-kspread-crypt':
+        return 'x-office-spreadsheet';
+
+      // Presentation document types.
+      case 'application/vnd.ms-powerpoint':
+      case 'application/vnd.ms-powerpoint.presentation.macroEnabled.12':
+      case 'application/vnd.oasis.opendocument.presentation':
+      case 'application/vnd.oasis.opendocument.presentation-template':
+      case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
+      case 'application/vnd.stardivision.impress':
+      case 'application/vnd.sun.xml.impress':
+      case 'application/vnd.sun.xml.impress.template':
+      case 'application/x-kpresenter':
+        return 'x-office-presentation';
+
+      // Compressed archive types.
+      case 'application/zip':
+      case 'application/x-zip':
+      case 'application/stuffit':
+      case 'application/x-stuffit':
+      case 'application/x-7z-compressed':
+      case 'application/x-ace':
+      case 'application/x-arj':
+      case 'application/x-bzip':
+      case 'application/x-bzip-compressed-tar':
+      case 'application/x-compress':
+      case 'application/x-compressed-tar':
+      case 'application/x-cpio-compressed':
+      case 'application/x-deb':
+      case 'application/x-gzip':
+      case 'application/x-java-archive':
+      case 'application/x-lha':
+      case 'application/x-lhz':
+      case 'application/x-lzop':
+      case 'application/x-rar':
+      case 'application/x-rpm':
+      case 'application/x-tzo':
+      case 'application/x-tar':
+      case 'application/x-tarz':
+      case 'application/x-tgz':
+        return 'package-x-generic';
+
+      // Script file types.
+      case 'application/ecmascript':
+      case 'application/javascript':
+      case 'application/mathematica':
+      case 'application/vnd.mozilla.xul+xml':
+      case 'application/x-asp':
+      case 'application/x-awk':
+      case 'application/x-cgi':
+      case 'application/x-csh':
+      case 'application/x-m4':
+      case 'application/x-perl':
+      case 'application/x-php':
+      case 'application/x-ruby':
+      case 'application/x-shellscript':
+      case 'text/javascript':
+      case 'text/vnd.wap.wmlscript':
+      case 'text/x-emacs-lisp':
+      case 'text/x-haskell':
+      case 'text/x-literate-haskell':
+      case 'text/x-lua':
+      case 'text/x-makefile':
+      case 'text/x-matlab':
+      case 'text/x-python':
+      case 'text/x-sql':
+      case 'text/x-tcl':
+        return 'text-x-script';
+
+      // HTML aliases.
+      case 'application/xhtml+xml':
+        return 'text-html';
+
+      // Executable types.
+      case 'application/x-macbinary':
+      case 'application/x-ms-dos-executable':
+      case 'application/x-pef-executable':
+        return 'application-x-executable';
+
+      // Acrobat types.
+      case 'application/pdf':
+      case 'application/x-pdf':
+      case 'applications/vnd.pdf':
+      case 'text/pdf':
+      case 'text/x-pdf':
+        return 'application-pdf';
+
+      default:
+        return FALSE;
+    }
+  }
+
+}
diff --git a/core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php b/core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php
index 88eb01bdc675..e3ff66a2bc5b 100644
--- a/core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php
+++ b/core/modules/file/tests/src/Kernel/LegacyFileModuleTest.php
@@ -27,4 +27,22 @@ public function testFileProgressDeprecation() {
     $this->assertFalse(\file_progress_implementation());
   }
 
+  /**
+   * @covers ::file_icon_map
+   */
+  public function testFileIconMapDeprecation(): void {
+    $this->expectDeprecation('file_icon_map() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\IconMimeTypes::getGenericMimeType() instead. See https://www.drupal.org/node/3411269');
+    $mimeType = \file_icon_map('application/msword');
+    $this->assertEquals('x-office-document', $mimeType);
+  }
+
+  /**
+   * @covers ::file_icon_class
+   */
+  public function testFileIconClassDeprecation(): void {
+    $this->expectDeprecation('file_icon_class() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use \Drupal\file\IconMimeTypes::getIconClass() instead. See https://www.drupal.org/node/3411269');
+    $iconClass = \file_icon_class('image/jpeg');
+    $this->assertEquals('image', $iconClass);
+  }
+
 }
-- 
GitLab