From c5f18bb6dc08a758ff735454bbe9cfa45a68c09b Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Wed, 15 Dec 2021 15:44:58 +0000
Subject: [PATCH] fix(import): add extension when downloading file without +
 truncate slug if too long

---
 app/Config/Mimes.php                          |  6 +++---
 .../Admin/PodcastImportController.php         | 14 +++++++------
 app/Helpers/media_helper.php                  |  8 ++++++--
 app/Helpers/misc_helper.php                   |  7 ++++++-
 app/Views/admin/podcast/import.php            | 20 +++++++++----------
 composer.lock                                 | 20 +++++++++----------
 6 files changed, 43 insertions(+), 32 deletions(-)

diff --git a/app/Config/Mimes.php b/app/Config/Mimes.php
index 794c58db60..dfb0287378 100644
--- a/app/Config/Mimes.php
+++ b/app/Config/Mimes.php
@@ -131,9 +131,9 @@ class Mimes
         'rar' => ['application/vnd.rar', 'application/x-rar', 'application/rar', 'application/x-rar-compressed'],
         'mid' => 'audio/midi',
         'midi' => 'audio/midi',
+        'mp3' => ['audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'],
         'mpga' => 'audio/mpeg',
         'mp2' => 'audio/mpeg',
-        'mp3' => ['audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'],
         'aif' => ['audio/x-aiff', 'audio/aiff'],
         'aiff' => ['audio/x-aiff', 'audio/aiff'],
         'aifc' => 'audio/x-aiff',
@@ -306,10 +306,10 @@ class Mimes
     /**
      * Attempts to determine the best file extension for a given mime type.
      *
-     * @param string|null $proposedExtension - default extension (in case there is more than one with the same mime type)
+     * @param string $proposedExtension - default extension (in case there is more than one with the same mime type)
      * @return string|null The extension determined, or null if unable to match.
      */
-    public static function guessExtensionFromType(string $type, string $proposedExtension = null): ?string
+    public static function guessExtensionFromType(string $type, string $proposedExtension = ''): ?string
     {
         $type = trim(strtolower($type), '. ');
 
diff --git a/app/Controllers/Admin/PodcastImportController.php b/app/Controllers/Admin/PodcastImportController.php
index 2832cf83b4..8d568395df 100644
--- a/app/Controllers/Admin/PodcastImportController.php
+++ b/app/Controllers/Admin/PodcastImportController.php
@@ -305,11 +305,10 @@ class PodcastImportController extends BaseController
             );
             $nsContent = $item->children('http://purl.org/rss/1.0/modules/content/');
 
-            $slug = slugify(
-                $this->request->getPost('slug_field') === 'title'
-                    ? (string) $item->title
-                    : basename((string) $item->link),
-            );
+            $textToSlugify = $this->request->getPost('slug_field') === 'title'
+            ? (string) $item->title
+            : basename((string) $item->link);
+            $slug = slugify($textToSlugify, 185);
             if (in_array($slug, $slugs, true)) {
                 $slugNumber = 2;
                 while (in_array($slug . '-' . $slugNumber, $slugs, true)) {
@@ -348,7 +347,10 @@ class PodcastImportController extends BaseController
                 'title' => $item->title,
                 'slug' => $slug,
                 'guid' => $item->guid ?? null,
-                'audio_file' => download_file((string) $item->enclosure->attributes()['url']),
+                'audio_file' => download_file(
+                    (string) $item->enclosure->attributes()['url'],
+                    (string) $item->enclosure->attributes()['type']
+                ),
                 'description_markdown' => $converter->convert($itemDescriptionHtml),
                 'description_html' => $itemDescriptionHtml,
                 'image' => $episodeImage,
diff --git a/app/Helpers/media_helper.php b/app/Helpers/media_helper.php
index 4e8ddd3f3d..46d0ced34c 100644
--- a/app/Helpers/media_helper.php
+++ b/app/Helpers/media_helper.php
@@ -11,6 +11,7 @@ declare(strict_types=1);
 use CodeIgniter\Files\File;
 use CodeIgniter\HTTP\Files\UploadedFile;
 use CodeIgniter\HTTP\ResponseInterface;
+use Config\Mimes;
 use Config\Services;
 
 if (! function_exists('save_media')) {
@@ -41,7 +42,7 @@ if (! function_exists('save_media')) {
 }
 
 if (! function_exists('download_file')) {
-    function download_file(string $fileUrl): File
+    function download_file(string $fileUrl, string $mimetype = ''): File
     {
         $client = Services::curlrequest();
 
@@ -75,12 +76,15 @@ if (! function_exists('download_file')) {
                 'http_errors' => false,
             ]);
         }
+
+        $fileExtension = pathinfo(parse_url($newFileUrl, PHP_URL_PATH), PATHINFO_EXTENSION);
+        $extension = $fileExtension === '' ? Mimes::guessExtensionFromType($mimetype) : $fileExtension;
         $tmpFilename =
             time() .
             '_' .
             bin2hex(random_bytes(10)) .
             '.' .
-            pathinfo(parse_url($newFileUrl, PHP_URL_PATH), PATHINFO_EXTENSION);
+            $extension;
         $tmpFilePath = WRITEPATH . 'uploads/' . $tmpFilename;
         file_put_contents($tmpFilePath, $response->getBody());
 
diff --git a/app/Helpers/misc_helper.php b/app/Helpers/misc_helper.php
index 212b8271ee..f45726b093 100644
--- a/app/Helpers/misc_helper.php
+++ b/app/Helpers/misc_helper.php
@@ -23,8 +23,13 @@ if (! function_exists('get_browser_language')) {
 }
 
 if (! function_exists('slugify')) {
-    function slugify(string $text): string
+    function slugify(string $text, int $maxLength = 191): string
     {
+        // trim text to the nearest whole word if too long
+        if (strlen($text) > $maxLength) {
+            $text = substr($text, 0, strrpos(substr($text, 0, $maxLength), ' '));
+        }
+
         // replace non letter or digits by -
         $text = preg_replace('~[^\pL\d]+~u', '-', $text);
 
diff --git a/app/Views/admin/podcast/import.php b/app/Views/admin/podcast/import.php
index 729f30bc34..bec1dd320d 100644
--- a/app/Views/admin/podcast/import.php
+++ b/app/Views/admin/podcast/import.php
@@ -89,29 +89,29 @@
 
 <?= form_fieldset('', ['class' => 'flex flex-col mb-4']) ?>
     <legend><?= lang('PodcastImport.slug_field.label') ?></legend>
-    <label for="link" class="inline-flex items-center">
+    <label for="title" class="inline-flex items-center">
         <?= form_radio(
             [
-                'id' => 'link',
+                'id' => 'title',
                 'name' => 'slug_field',
                 'class' => 'form-radio text-pine-700',
             ],
-            'link',
-            old('slug_field') ? old('slug_field') == 'link' : true,
+            'title',
+            old('slug_field') ? old('slug_field') === 'title' : true,
         ) ?>
-        <span class="ml-2"><?= lang('PodcastImport.slug_field.link') ?></span>
+        <span class="ml-2"><?= lang('PodcastImport.slug_field.title') ?></span>
     </label>
-    <label for="title" class="inline-flex items-center">
+    <label for="link" class="inline-flex items-center">
         <?= form_radio(
             [
-                'id' => 'title',
+                'id' => 'link',
                 'name' => 'slug_field',
                 'class' => 'form-radio text-pine-700',
             ],
-            'title',
-            old('slug_field') && old('slug_field') == 'title',
+            'link',
+            old('slug_field') && old('slug_field') === 'link',
         ) ?>
-        <span class="ml-2"><?= lang('PodcastImport.slug_field.title') ?></span>
+        <span class="ml-2"><?= lang('PodcastImport.slug_field.link') ?></span>
     </label>
 <?= form_fieldset_close() ?>
 
diff --git a/composer.lock b/composer.lock
index c51543a008..9258e2efa1 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
     "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
     "This file is @generated automatically"
   ],
-  "content-hash": "371c6aac9ca489338bf3b3fa06ffdb21",
+  "content-hash": "49719de3dd6af8c394ea0553e2180b5a",
   "packages": [
     {
       "name": "brick/math",
@@ -494,24 +494,24 @@
     },
     {
       "name": "james-heinrich/getid3",
-      "version": "v2.0.0-beta3",
+      "version": "v2.0.0-beta4",
       "source": {
         "type": "git",
         "url": "https://github.com/JamesHeinrich/getID3.git",
-        "reference": "5515a2d24667c3c0ff49fdcbdadc405c0880c7a2"
+        "reference": "5ad79104e937e7d9c8a9141a97e1f063dd1123f8"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/JamesHeinrich/getID3/zipball/5515a2d24667c3c0ff49fdcbdadc405c0880c7a2",
-        "reference": "5515a2d24667c3c0ff49fdcbdadc405c0880c7a2",
+        "url": "https://api.github.com/repos/JamesHeinrich/getID3/zipball/5ad79104e937e7d9c8a9141a97e1f063dd1123f8",
+        "reference": "5ad79104e937e7d9c8a9141a97e1f063dd1123f8",
         "shasum": ""
       },
       "require": {
         "php": ">=5.4.0"
       },
       "require-dev": {
-        "jakub-onderka/php-parallel-lint": "^0.9 || ^1.0",
-        "phpunit/phpunit": "^4.8|^5.0"
+        "php-parallel-lint/php-parallel-lint": "^1.0",
+        "phpunit/phpunit": "^4.8 || ^5.0 || ^6.1 || ^7.5 || ^8.5"
       },
       "suggest": {
         "ext-SimpleXML": "SimpleXML extension is required to analyze RIFF/WAV/BWF audio files (also requires `ext-libxml`).",
@@ -562,9 +562,9 @@
       "keywords": ["audio", "codecs", "id3", "metadata", "tags", "video"],
       "support": {
         "issues": "https://github.com/JamesHeinrich/getID3/issues",
-        "source": "https://github.com/JamesHeinrich/getID3/tree/2.0"
+        "source": "https://github.com/JamesHeinrich/getID3/tree/v2.0.0-beta4"
       },
-      "time": "2020-07-21T08:15:44+00:00"
+      "time": "2021-10-06T16:23:45+00:00"
     },
     {
       "name": "kint-php/kint",
@@ -7465,5 +7465,5 @@
     "php": "^8.0"
   },
   "platform-dev": [],
-  "plugin-api-version": "2.0.0"
+  "plugin-api-version": "2.1.0"
 }
-- 
GitLab