]> git.agnieray.net Git - galette.git/commitdiff
Parametize members cards sizes
authorTheFab21 <121039071+TheFab21@users.noreply.github.com>
Mon, 8 Apr 2024 14:45:12 +0000 (16:45 +0200)
committerJohan Cwiklinski <johan@x-tnd.be>
Sat, 4 May 2024 06:51:36 +0000 (08:51 +0200)
closes #1817

galette/docs/CHANGES
galette/lib/Galette/Controllers/AuthController.php
galette/lib/Galette/Controllers/GaletteController.php
galette/lib/Galette/Core/Preferences.php
galette/lib/Galette/IO/PdfMembersCards.php
galette/templates/default/pages/preferences.html.twig
tests/Galette/Core/tests/units/Preferences.php

index 03ae3f0140ed3a32f6aa7120b39a66b5f828ab96..9898b88d0d136b7d0970fc2ff4819639d9a884c2 100644 (file)
@@ -30,6 +30,7 @@ Changes
 - Add payment type on transactions
 - Remove non user related files from cofiguration folder
 - Add monthly contribution membership
+- PDF Member card adaptative size
 
 1.0.3 -> 1.0.4
 
index fbffe67e6bc88eda2ef45e5217b41032aaea8d0b..46c09038506abe39fb47a103ab1c25612d13dee6 100644 (file)
@@ -122,11 +122,24 @@ class AuthController extends AbstractController
                 || $this->login->isAdmin()
                 || $this->login->isStaff()
             ) {
-                if (defined('NON_UTF_DBCONNECT')) {
-                    $this->flash->addMessage(
-                        'warning',
-                        'It appears you are using NON_UTF_DBCONNECT constant, that has been removed in current release.'
-                    );
+                $deprecated_constants = [
+                    'NON_UTF_DBCONNECT',
+                    'GALETTE_CARD_WIDTH',
+                    'GALETTE_CARD_HEIGHT',
+                    'GALETTE_CARD_COLS',
+                    'GALETTE_CARD_ROWS'
+                ];
+
+                foreach ($deprecated_constants as $deprecated_constant) {
+                    if (defined($deprecated_constant)) {
+                        $this->flash->addMessage(
+                            'warning',
+                            sprintf(
+                                'It appears you are using %1$s constant, that has been removed in current release.',
+                                $deprecated_constant
+                            )
+                        );
+                    }
                 }
 
                 try {
index 816e7b781ebdf5b844578135be1ff048c097cd15..91bcce74ec423c9ee74e0dc5b725e4a65b98c958 100644 (file)
@@ -258,7 +258,6 @@ class GaletteController extends AbstractController
     {
         $post = $request->getParsedBody();
         $error_detected = [];
-        $warning_detected = [];
 
         // Validation
         if (isset($post['valid']) && $post['valid'] == '1') {
@@ -271,7 +270,6 @@ class GaletteController extends AbstractController
                         _T("Preferences has been saved.")
                     );
                 }
-                $warning_detected = array_merge($warning_detected, $this->preferences->checkCardsSizes());
 
                 // picture upload
                 if (!Galette::isDemo() && isset($_FILES['logo'])) {
@@ -350,16 +348,6 @@ class GaletteController extends AbstractController
                     );
                 }
             }
-
-            if (count($warning_detected) > 0) {
-                //report warnings
-                foreach ($warning_detected as $warning) {
-                    $this->flash->addMessage(
-                        'warning_detected',
-                        $warning
-                    );
-                }
-            }
         }
         if (isset($post['tab']) && $post['tab'] != 'general') {
             $tab = '?tab=' . $post['tab'];
index c9cab5d21e925239f53c074c9629586eccee9f16..933ae6ec88feb0fe4697275b623975cf4af125d3 100644 (file)
@@ -241,6 +241,10 @@ class Preferences
         'pref_card_bcol'    =>    '#53248C',
         'pref_card_hcol'    =>    '#248C53',
         'pref_bool_display_title'    =>    false,
+        'pref_card_hsize'    =>    84,
+        'pref_card_vsize'    =>    52,
+        'pref_card_rows'    =>    6,
+        'pref_card_cols'    =>    2,
         'pref_card_address'    =>    1,
         'pref_card_year'    =>    '',
         'pref_card_marges_v'    =>    15,
@@ -307,7 +311,9 @@ class Preferences
         'pref_card_marges_v',
         'pref_card_marges_h',
         'pref_card_hspace',
-        'pref_card_vspace'
+        'pref_card_vspace',
+        'pref_card_hsize',
+        'pref_card_vsize'
     );
 
     /**
@@ -704,6 +710,16 @@ class Preferences
                     $this->errors[] = _T("- The numbers and measures have to be integers!");
                 }
                 break;
+            case 'pref_card_vsize':
+                if (!is_numeric($value) || $value < 40 || $value > 55) {
+                    $this->errors[] = _T("- The card height have to be an integer between 40 and 55!");
+                }
+                break;
+            case 'pref_card_hsize':
+                if (!is_numeric($value) || $value < 70 || $value > 95) {
+                    $this->errors[] = _T("- The card width have to be an integer between 75 and 95!");
+                }
+                break;
             case 'pref_card_tcol':
             case 'pref_card_scol':
             case 'pref_card_bcol':
@@ -808,6 +824,14 @@ class Preferences
                     }
                     $value = $v;
                 }
+                if ($k === 'pref_card_cols') {
+                    $v = PdfMembersCards::getCols();
+                    $value = $v;
+                }
+                if ($k === 'pref_card_rows') {
+                    $v = PdfMembersCards::getRows();
+                    $value = $v;
+                }
 
                 $stmt->execute(
                     array(
@@ -1155,41 +1179,6 @@ class Preferences
         return null;
     }
 
-    /**
-     * Check member cards sizes
-     * Always a A4/portrait
-     *
-     * @return array<string>
-     */
-    public function checkCardsSizes(): array
-    {
-        $warning_detected = [];
-        //check page width
-        $max = 210;
-        //margins
-        $size = $this->pref_card_marges_h * 2;
-        //cards
-        $size += PdfMembersCards::getWidth() * PdfMembersCards::getCols();
-        //spacing
-        $size += $this->pref_card_hspace * (PdfMembersCards::getCols() - 1);
-        if ($size > $max) {
-            $warning_detected[] = _T('Current cards configuration may exceed page width!');
-        }
-
-        $max = 297;
-        //margins
-        $size = $this->pref_card_marges_v * 2;
-        //cards
-        $size += PdfMembersCards::getHeight() * PdfMembersCards::getRows();
-        //spacing
-        $size += $this->pref_card_vspace * (PdfMembersCards::getRows() - 1);
-        if ($size > $max) {
-            $warning_detected[] = _T('Current cards configuration may exceed page height!');
-        }
-
-        return $warning_detected;
-    }
-
     /**
      * Get errors
      *
index af37a141286492f977b142272a2b9bbf49b67f72..181de142beb34cba47e1d76ff49a46463617f37c 100644 (file)
@@ -36,10 +36,8 @@ use Galette\Repository\Members;
 
 class PdfMembersCards extends Pdf
 {
-    public const WIDTH = 75;
-    public const HEIGHT = 40;
-    public const COLS = 2;
-    public const ROWS = 6;
+    public const PAGE_WIDTH = 210;
+    public const PAGE_HEIGHT = 297;
 
     /** @var array<string,float|int> */
     private array $tcol;
@@ -134,8 +132,8 @@ class PdfMembersCards extends Pdf
         $this->vspacing = $this->preferences->pref_card_vspace;
 
         //maximum size for visible text. May vary with fonts.
-        $this->max_text_size = 80;
-        $this->year_font_size = 8;
+        $this->max_text_size = self::getWidth() - (int)round($this->wi / 3.5) - 2;
+        $this->year_font_size = (int)round(self::getWidth() / 7);
 
         // Get fixed data from preferences
         $this->an_cot = $this->preferences->pref_card_year;
@@ -144,19 +142,19 @@ class PdfMembersCards extends Pdf
         $print_logo = new PrintLogo();
         $this->logofile = $print_logo->getPath();
 
-        // Set logo size to max width 30mm (113px) or max height 17mm (64px)
+        // Set logo size to max 20% width  or max 25% height
         $ratio = $print_logo->getWidth() / $print_logo->getHeight();
         if ($ratio < 1.71) {
-            if ($print_logo->getHeight() > 64) {
-                $this->hlogo = 17;
+            if ($print_logo->getHeight() > 0.25 * $this->wi * 3.78) {
+                $this->hlogo = round(0.25 * $this->wi);
             } else {
                 // Convert original pixels size to millimeters
                 $this->hlogo = $print_logo->getHeight() / 3.78;
             }
             $this->wlogo = round($this->hlogo * $ratio);
         } else {
-            if ($print_logo->getWidth() > 113) {
-                $this->wlogo = 30;
+            if ($print_logo->getWidth() > 0.2 * $this->he * 3.78) {
+                $this->wlogo = round(0.2 * $this->he);
             } else {
                 // Convert original pixels size to millimeters
                 $this->wlogo = $print_logo->getWidth() / 3.78;
@@ -237,8 +235,8 @@ class PdfMembersCards extends Pdf
             $photofile = $photo->getPath();
 
             // Photo 100x130 and logo
-            $this->Image($photofile, $x0, $y0, 25);
-            $this->Image($this->logofile, $xl, $y0, round($this->wlogo));
+            $this->Image($photofile, $x0 + 1, $y0 + 1, round($this->wi / 3.5));
+            $this->Image($this->logofile, $xl - 1, $y0 + 1, round($this->wlogo));
 
             // Color=#8C8C8C: Shadow of the year
             $this->SetTextColor(140);
@@ -250,15 +248,14 @@ class PdfMembersCards extends Pdf
                 $an_cot = $member->due_date;
             }
 
-            $xan_cot = $x0 + $this->wi - $this->GetStringWidth(
+            $xan_cot = $x0 + $this->wi / 2 - $this->GetStringWidth(
                 $an_cot,
                 self::FONT,
                 'B',
                 $this->year_font_size
-            ) - 0.2;
-            $this->SetXY($xan_cot, $y0 + $this->hlogo - 0.3);
+            ) / 2 ;
+            $this->SetXY($xan_cot, $y0 + 1);
             $this->writeHTML('<strong>' . $an_cot . '</strong>', false, false);
-
             // Colored Text (Big label, id, year)
             $this->SetTextColor($fcol['R'], $fcol['G'], $fcol['B']);
 
@@ -266,13 +263,13 @@ class PdfMembersCards extends Pdf
 
             if (!empty($this->preferences->pref_show_id) || !empty($member->number)) {
                 $member_id = (!empty($member->number)) ? $member->number : $member->id;
-                $xid = $x0 + $this->wi - $this->GetStringWidth($member_id, self::FONT, 'B', 8) - 0.2;
-                $this->SetXY($xid, $y0 + 28);
-                $this->writeHTML('<strong>' . $member_id . '</strong>', false, false);
+                $xid = $x0 + $this->wi / 2 - $this->GetStringWidth(_T("Member") . ' n° : ' . $member_id, self::FONT, 'B', 8) / 2;
+                $this->SetXY($xid, $y0 + 8);
+                $this->writeHTML('<strong>' . _T("Member") . ' n° : ' . $member_id . '  </strong>', false, false);
             }
             $this->SetFontSize($this->year_font_size);
-            $xan_cot = $xan_cot - 0.3;
-            $this->SetXY($xan_cot, $y0 + $this->hlogo - 0.3);
+            $xan_cot = $xan_cot - 0.1;
+            $this->SetXY($xan_cot, $y0 + 1 - 0.1);
             $this->writeHTML('<strong>' . $an_cot . '</strong>', false, false);
 
             // Abbrev: Adapt font size to text length
@@ -282,7 +279,8 @@ class PdfMembersCards extends Pdf
                 12,
                 'B'
             );
-            $this->SetXY($x0 + 27, $y0 + 12);
+            $xid = $x0 + $this->wi / 2 - $this->GetStringWidth($this->abrev, self::FONT, 'B', 12) / 2;
+            $this->SetXY($xid, $y0 + 12);
             $this->writeHTML('<strong>' . $this->abrev . '</strong>', true, false);
 
             // Name: Adapt font size to text length
@@ -293,7 +291,7 @@ class PdfMembersCards extends Pdf
                 8,
                 'B'
             );
-            $this->SetXY($x0 + 27, $this->getY() + 4);
+            $this->SetXY($x0 + round($this->wi / 3.5) + 2, $y0 + $this->hlogo + 3);
             //$this->setX($x0 + 27);
             $this->writeHTML('<strong>' . $nom_adh_ext . '</strong>', true, false);
 
@@ -304,7 +302,7 @@ class PdfMembersCards extends Pdf
                 6,
                 'B'
             );
-            $this->setX($x0 + 27);
+            $this->setX($x0 + round($this->wi / 3.5) + 2);
             $this->writeHTML('<strong>' . $email . '</strong>', false, false);
 
             // Lower colored strip with long text
@@ -314,11 +312,11 @@ class PdfMembersCards extends Pdf
                 $this->tcol['G'],
                 $this->tcol['B']
             );
-            $this->SetFont(self::FONT, 'B', 6);
-            $this->SetXY($x0, $y0 + 33);
+            $this->SetFont(self::FONT, 'B', 8);
+            $this->SetXY($x0, $y0 + round($this->wi / 3.5) * 1.3 + 2);
             $this->Cell(
                 $this->wi,
-                7,
+                ($this->he - (round($this->wi / 3.5) * 1.3 + 2)),
                 $this->preferences->pref_card_strip,
                 0,
                 0,
@@ -339,7 +337,9 @@ class PdfMembersCards extends Pdf
      */
     public static function getWidth(): int
     {
-        return defined('GALETTE_CARD_WIDTH') ? GALETTE_CARD_WIDTH : self::WIDTH;
+        global $preferences;
+
+        return $preferences->pref_card_hsize ;
     }
 
     /**
@@ -349,7 +349,9 @@ class PdfMembersCards extends Pdf
      */
     public static function getHeight(): int
     {
-        return defined('GALETTE_CARD_HEIGHT') ? GALETTE_CARD_HEIGHT : self::HEIGHT;
+        global $preferences;
+
+        return $preferences->pref_card_vsize ;
     }
 
     /**
@@ -359,7 +361,20 @@ class PdfMembersCards extends Pdf
      */
     public static function getCols(): int
     {
-        return defined('GALETTE_CARD_COLS') ? GALETTE_CARD_COLS : self::COLS;
+        global $preferences;
+
+        $margins = $preferences->pref_card_marges_h * 2;
+
+        $nbcols = (int)round(
+            ((self::PAGE_WIDTH - $margins) / $preferences->pref_card_hsize),
+            0,
+            PHP_ROUND_HALF_DOWN
+        );
+        if ((($nbcols - 1) * $preferences->pref_card_hspace + $margins + $preferences->pref_card_hsize *  $nbcols) > self::PAGE_WIDTH) {
+            --$nbcols;
+        }
+
+        return $nbcols;
     }
 
     /**
@@ -369,6 +384,19 @@ class PdfMembersCards extends Pdf
      */
     public static function getRows(): int
     {
-        return defined('GALETTE_CARD_ROWS') ? GALETTE_CARD_ROWS : self::ROWS;
+        global $preferences;
+
+        $margins = $preferences->pref_card_marges_v * 2;
+
+        $nbrows = (int)round(
+            ((self::PAGE_HEIGHT - $margins) / $preferences->pref_card_vsize),
+            0,
+            PHP_ROUND_HALF_DOWN
+        );
+        if ((($nbrows - 1) * $preferences->pref_card_vspace + $margins + $preferences->pref_card_vsize *  $nbrows) > self::PAGE_HEIGHT) {
+            --$nbrows;
+        }
+
+        return $nbrows;
     }
 }
index 909d72e13a5a029e18d70dbe00fc5a73208610bb..d3c57b2ecd1a7ac680a6cf0d245229ec7b14c957 100644 (file)
             <div class="ui icon info visible message">
                 <i class="info circle blue icon" aria-hidden="true"></i>
                 <div class="content">
-                    {{ _T("Each card is 75mm width and 40mm height. Each page contains 2 columns and 6 rows.<br/>Double check margins and spacings ;)")|raw }}
+                    {{ _T("Each page contains %1$s columns and  %2$s rows.")|replace({"%1$s": pref.pref_card_cols, "%2$s": pref.pref_card_rows}) }}
                 </div>
             </div>
             <div class="ui stackable two column grid">
                             <div class="ui basic label">mm</div>
                         </div>
                     </div>
+                    <div class="{% if required.pref_card_hsize is defined and required.pref_card_hsize == 1 %}required {% endif %}field">
+                        <label for="pref_card_hsize">{{ _T("Card width from 70 to 95mm:") }}</label>
+                        <div class="ui right labeled input">
+                            <input type="number" name="pref_card_hsize" id="pref_card_hsize" value="{{ pref.pref_card_hsize }}" maxlength="4"{% if required.pref_card_hsize is defined and required.pref_card_hsize == 1 %} required="required"{% endif %}/>
+                            <div class="ui basic label">mm</div>
+                        </div>
+                    </div>
+                    <div class="{% if required.pref_card_vsize is defined and required.pref_card_vsize == 1 %}required {% endif %}field">
+                        <label for="pref_card_vsize">{{ _T("Card height from 40 to 55mm:") }}</label>
+                        <div class="ui right labeled input">
+                            <input type="number" name="pref_card_vsize" id="pref_card_vsize" value="{{ pref.pref_card_vsize }}" maxlength="4"{% if required.pref_card_vsize is defined and required.pref_card_vsize == 1 %} required="required"{% endif %}/>
+                            <div class="ui basic label">mm</div>
+                        </div>
+                    </div>
                 </div>{# /column #}
             </div>{# /column grid #}
         </div>{# /tab segment #}
index b638956f4f051a4f50c046059d3b91d575ff3367..b8fa9d22854238bb4133c4720a57e7d82dc2594a 100644 (file)
@@ -287,76 +287,6 @@ class Preferences extends TestCase
         $this->assertFalse($visible);
     }
 
-    /**
-     * Data provider for cards sizes tests
-     *
-     * @return array
-     */
-    public static function sizesProvider(): array
-    {
-        return [
-            [//defaults
-                15, //vertical margin
-                20, //horizontal margin
-                5,  //vertical spacing
-                10, //horizontal spacing
-                0   //expected number of warnings
-            ], [ //OK
-                0,  //vertical margin
-                20, //horizontal margin
-                11, //vertical spacing
-                10, //horizontal spacing
-                0   //expected number of warnings
-            ], [ //vertical overflow
-                0,  //vertical margin
-                20, //horizontal margin
-                12, //vertical spacing
-                10, //horizontal spacing
-                1   //expected number of warnings
-            ], [//horizontal overflow
-                15, //vertical margin
-                20, //horizontal margin
-                5,  //vertical spacing
-                61, //horizontal spacing
-                1   //expected number of warnings
-            ], [//vertical and horizontal overflow
-                0,  //vertical margin
-                20, //horizontal margin
-                12, //vertical spacing
-                61, //horizontal spacing
-                2   //expected number of warnings
-            ], [//vertical overflow
-                17, //vertical margin
-                20, //horizontal margin
-                5,  //vertical spacing
-                10, //horizontal spacing
-                1   //expected number of warnings
-            ]
-        ];
-    }
-
-    /**
-     * Test checkCardsSizes
-     *
-     * @dataProvider sizesProvider
-     *
-     * @param integer $vm    Vertical margin
-     * @param integer $hm    Horizontal margin
-     * @param integer $vs    Vertical spacing
-     * @param integer $hs    Horizontal spacing
-     * @param integer $count Number of expected errors
-     *
-     * @return void
-     */
-    public function testCheckCardsSizes(int $vm, int $hm, int $vs, int $hs, int $count): void
-    {
-        $this->preferences->pref_card_marges_v = $vm;
-        $this->preferences->pref_card_marges_h = $hm;
-        $this->preferences->pref_card_vspace = $vs;
-        $this->preferences->pref_card_hspace = $hs;
-        $this->assertCount($count, $this->preferences->checkCardsSizes());
-    }
-
     /**
      * Data provider for colors
      *