Browse Source

fix cmf licence export with large organizations names

Olivier Massot 3 months ago
parent
commit
4ff9a7152a

+ 6 - 4
src/Service/Export/LicenceCmfExporter.php

@@ -11,6 +11,7 @@ use App\Enum\Core\FileTypeEnum;
 use App\Repository\Organization\OrganizationRepository;
 use App\Service\Export\Model\LicenceCmf;
 use App\Service\Export\Model\LicenceCmfCollection;
+use App\Service\Utils\StringsUtils;
 
 /**
  * Exporte la licence CMF de la structure ou du ou des access, au format demandé.
@@ -49,12 +50,12 @@ class LicenceCmfExporter extends BaseExporter implements ExporterInterface
         $licenceCmf->setId($organization->getId());
         $licenceCmf->setYear($exportRequest->getYear());
         $licenceCmf->setIsOrganizationLicence($exportRequest instanceof LicenceCmfOrganizationER);
-        $licenceCmf->setOrganizationName($organization->getName());
+        $licenceCmf->setOrganizationName(StringsUtils::elide($organization->getName(), 64));
         $licenceCmf->setOrganizationIdentifier($organization->getIdentifier());
 
         $parentFederation = $organization->getNetworkOrganizations()->get(0)?->getParent();
         if ($parentFederation !== null) {
-            $licenceCmf->setFederationName($parentFederation->getName());
+            $licenceCmf->setFederationName(StringsUtils::elide($parentFederation->getName(), 64));
         }
 
         $licenceCmf->setColor(
@@ -72,8 +73,8 @@ class LicenceCmfExporter extends BaseExporter implements ExporterInterface
             if ($president !== null) {
                 $licenceCmf->setPersonId($president->getId());
                 $licenceCmf->setPersonGender($president->getGender() ?? null);
-                $licenceCmf->setPersonFirstName($president->getGivenName());
-                $licenceCmf->setPersonLastName($president->getName());
+                $licenceCmf->setPersonFirstName(StringsUtils::elide($president->getGivenName(), 64));
+                $licenceCmf->setPersonLastName(StringsUtils::elide($president->getName(), 64));
             }
         }
 
@@ -117,4 +118,5 @@ class LicenceCmfExporter extends BaseExporter implements ExporterInterface
 
         return self::LICENCE_CMF_COLOR[($year - self::LICENCE_CMF_COLOR_START_YEAR) % count(self::LICENCE_CMF_COLOR)];
     }
+
 }

+ 13 - 0
src/Service/Utils/StringsUtils.php

@@ -45,4 +45,17 @@ class StringsUtils
     {
         return strip_tags(preg_replace('{<(head|style)\b.*?</\1>}is', '', $html));
     }
+
+    /**
+     * Tronque un nom au nombre de caractères maximum demandé et ajoute "..." si nécessaire.
+     *
+     * @see StringsUtilsTest::testElide()
+     */
+    public static function elide(string $str, int $length): string
+    {
+        if ($length <= 5) {
+            throw new \InvalidArgumentException('Length must be greater than 5');
+        }
+        return mb_strlen($str) > $length ? mb_substr($str, 0, $length - 3) . '...' : $str;
+    }
 }

+ 2 - 2
templates/export/licence_cmf.html.twig

@@ -269,10 +269,10 @@
                                     <div align="center">
                                         {% if(licence.logo is null) %}
                                             <img src="{{ asset_base64('images/picto_face.png') }}"
-                                                 height="62"/>
+                                                 height="62" style="max-width: 76px; max-height: 62px"/>
                                         {% else %}
                                             <img src="{{ fileImagePath(licence.logo, 'sm') }}"
-                                                 height="62"/>
+                                                 height="62" style="max-width: 76px; max-height: 62px"/>
                                         {% endif %}
                                     </div>
                                 </td>

+ 53 - 0
tests/Unit/Service/Utils/StringsUtilsTest.php

@@ -32,4 +32,57 @@ class StringsUtilsTest extends TestCase
     {
         $this->assertEquals('Test contenu', (new StringsUtils())->convertHtmlToText('<table><tr><td>Test</td></tr></table> <br /><p>contenu</p>'));
     }
+
+    /**
+     * @see StringsUtils::elide()
+     */
+    public function testElide(): void
+    {
+        // Test normal truncation case - string longer than length
+        $this->assertEquals('Hello...', StringsUtils::elide('Hello World!', 8));
+
+        // Test case where string is shorter than length - no truncation
+        $this->assertEquals('Hello', StringsUtils::elide('Hello', 10));
+
+        // Test edge case with exact length
+        $this->assertEquals('Hello', StringsUtils::elide('Hello', 6));
+
+        // Test with empty string
+        $this->assertEquals('', StringsUtils::elide('', 10));
+    }
+
+    /**
+     * @see StringsUtils::elide()
+     */
+    public function testElideWithMultibyteCharacters(): void
+    {
+        // Test with UTF-8 multibyte characters
+        $this->assertEquals('Héllo...', StringsUtils::elide('Héllo Wörld!', 8));
+        $this->assertEquals('测试中...', StringsUtils::elide('测试中文字符串', 6));
+        $this->assertEquals('🎉🎊🎈🎆🎇', StringsUtils::elide('🎉🎊🎈🎆🎇', 6));
+    }
+
+    /**
+     * @see StringsUtils::elide()
+     */
+    public function testElideWithInvalidLength(): void
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Length must be greater than 5');
+
+        StringsUtils::elide('Hello World!', 1);
+    }
+
+    /**
+     * @see StringsUtils::elide()
+     */
+    public function testElideWithLongString(): void
+    {
+        $longString = str_repeat('A', 1000);
+        $result = StringsUtils::elide($longString, 50);
+
+        $this->assertEquals(50, mb_strlen($result)); // 47 + 3 dots
+        $this->assertTrue(str_ends_with($result, '...'));
+        $this->assertEquals(str_repeat('A', 47) . '...', $result);
+    }
 }