diff --git a/composer.json b/composer.json
index 5b22c5eac4458b906fb96e40dd101598184a8776..6c56b97bb52d4833dea08c588b8ceb6bd47fdcff 100644
--- a/composer.json
+++ b/composer.json
@@ -99,6 +99,7 @@
         "ext-pdo": "*",
         "ext-mbstring": "*",
         "ext-dom": "*",
+        "ext-iconv": "*",
         "opis/json-schema": "2.3.0",
         "slim/slim": "4.13.0",
         "php-di/php-di": "7.0.0",
diff --git a/lib/classes/ZipArchive.php b/lib/classes/ZipArchive.php
index f0b96967245763309d1ef884942ea7fa8ad636a1..0ddc6fa19b275c9ca4fad0a081df5deebbeeef87 100644
--- a/lib/classes/ZipArchive.php
+++ b/lib/classes/ZipArchive.php
@@ -1,12 +1,6 @@
 <?php
 namespace Studip;
 
-if (version_compare(phpversion('zip'), '1.18') < 0) {
-    require_once __DIR__ . '/ZipArchiveLegacyTrait.php';
-} else {
-    require_once __DIR__ . '/ZipArchiveTrait.php';
-}
-
 /**
  * Custom derived ZipArchive class with convenience methods for
  * zip archive handling.
@@ -19,8 +13,6 @@ if (version_compare(phpversion('zip'), '1.18') < 0) {
  */
 class ZipArchive extends \ZipArchive
 {
-    use ZipArchiveTrait;
-
     /**
      * @var string encoding for filenames in zip
      */
@@ -47,7 +39,7 @@ class ZipArchive extends \ZipArchive
      *     shall have the .zip file extension (true) or not (false).
      *     Defaults to false.
      *
-     * @return Studip\ZipArchive
+     * @return static
      */
     public static function create($filename, $force_zip_extension = false)
     {
@@ -141,8 +133,8 @@ class ZipArchive extends \ZipArchive
      * Adds all files from a certain path.
      *
      * @param String $path Path name to add
-     * @return Array of local filenames
-     * @uses Studip\ZipArchive::addFile
+     * @return array of local filenames
+     * @uses ZipArchive::addFile
      */
     public function addFromPath($path, $folder = '')
     {
@@ -155,13 +147,34 @@ class ZipArchive extends \ZipArchive
                     $result,
                     $this->addFromPath($file, $folder . basename($file) . '/')
                 );
-            } else {
-                $result[] = $this->addFile($file, $folder . basename($file));
+            } elseif ($this->addFile($file, $folder . basename($file))) {
+                $result[] = $this->convertLocalFilename($folder . basename($file));
             }
         }
         return array_filter($result);
     }
 
+    /**
+     * Adds a single file.
+     *
+     * @param string $filepath  Name of the file to add
+     * @param ?string $entryname Name of the file inside the archive,
+     *                           will default to $filename
+     * @param int    $start     Unused but required (according to php doc)
+     * @param int    $length    Unused but required (according to php doc)
+     * @param int    $flags     Bitmask (see https://php.net/ziparchive.addfile)
+     */
+    public function addFile(
+        string $filepath,
+        string $entryname = null,
+        int $start = 0,
+        int $length = 0,
+        int $flags = self::FL_OVERWRITE
+    ): bool {
+        $localname = $this->convertLocalFilename($entryname ?: basename($filepath));
+        return parent::addFile($filepath, $localname, $start, $length, $flags);
+    }
+
     /**
      * Converts the filename to a format that a zip file should be able
      * to handle.
@@ -171,7 +184,7 @@ class ZipArchive extends \ZipArchive
      */
     public function convertLocalFilename($filename)
     {
-        if ($this->output_encoding != 'UTF-8') {
+        if ($this->output_encoding !== 'UTF-8') {
             return iconv('UTF-8', $this->output_encoding . '//TRANSLIT', $filename);
         } else {
             return $filename;
diff --git a/lib/classes/ZipArchiveLegacyTrait.php b/lib/classes/ZipArchiveLegacyTrait.php
deleted file mode 100644
index 6fd5bfcc2ce180fe218d1955600fee3448721bba..0000000000000000000000000000000000000000
--- a/lib/classes/ZipArchiveLegacyTrait.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-namespace Studip;
-
-/**
- * Trait that handles the different method signatures in addFile() due to
- * changes in the Zip module since v1.18. This is the legacy part.
- */
-trait ZipArchiveTrait
-{
-    /**
-     * Adds a single file.
-     *
-     * @param String $filename Name of the file to add
-     * @param String $localname Name of the file inside the archive,
-     *                          will default to $filename
-     * @param int $start Unused but required (according to php doc)
-     * @param int $length Unused but required (according to php doc)
-     * @return false on error, $localname otherwise
-     */
-    public function addFile($filename, $localname = null, $start = 0, $length = 0)
-    {
-        $localname = $this->convertLocalFilename($localname ?: basename($filename));
-        return parent::addFile($filename, $localname, $start, $length)
-            ? $localname
-            : false;
-    }
-}
diff --git a/lib/classes/ZipArchiveTrait.php b/lib/classes/ZipArchiveTrait.php
deleted file mode 100644
index 803a5e1b1df15dbb2b93fb5a8fca21f55c35b2d8..0000000000000000000000000000000000000000
--- a/lib/classes/ZipArchiveTrait.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-namespace Studip;
-
-/**
- * Trait that handles the different method signatures in addFile() due to
- * changes in the Zip module since v1.18. This is the regular part.
- */
-trait ZipArchiveTrait
-{
-    /**
-     * Adds a single file.
-     *
-     * @param String $filename Name of the file to add
-     * @param String $localname Name of the file inside the archive,
-     *                          will default to $filename
-     * @param int $start Unused but required (according to php doc)
-     * @param int $length Unused but required (according to php doc)
-     * @param int $flags Bitmask (see https://php.net/ziparchive.addfile)
-     * @return false on error, $localname otherwise
-     */
-    public function addFile($filename, $localname = null, $start = 0, $length = 0, $flags = \ZipArchive::FL_OVERWRITE)
-    {
-        $localname = $this->convertLocalFilename($localname ?: basename($filename));
-        return parent::addFile($filename, $localname, $start, $length, $flags)
-            ? $localname
-            : false;
-    }
-}