]> git.agnieray.net Git - galette.git/commitdiff
Add and use isForeignKeyException, fix isDuplicateException
authorJohan Cwiklinski <johan@x-tnd.be>
Mon, 27 Nov 2023 13:05:18 +0000 (14:05 +0100)
committerJohan Cwiklinski <johan@x-tnd.be>
Tue, 28 Nov 2023 13:19:26 +0000 (14:19 +0100)
PostgreSQL exception codes are different, while mysql are the same, but
we have distinct coees in errInfo[1] entry.

see:
- https://www.postgresql.org/docs/current/errcodes-appendix.html
- https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html

Add test on members removal

galette/lib/Galette/Core/Db.php
galette/lib/Galette/Core/MailingHistory.php
galette/lib/Galette/Entity/Group.php
galette/lib/Galette/Repository/Members.php
tests/Galette/Repository/tests/units/Members.php

index 52d2aa1b23cde01d50a903499e2dc26494005e0f..ef1391c06483691565f19f6df703b3a0510430ed 100644 (file)
@@ -797,7 +797,7 @@ class Db
                 $msg . ' ' . $e->__toString(),
                 Analog::ERROR
             );
-            if ($sql instanceof Insert && $this->isDuplicateException($e)) {
+            if ($this->isDuplicateException($sql, $e)) {
                 throw new \OverflowException('Duplicate entry', 0, $e);
             }
             throw $e;
@@ -939,16 +939,34 @@ class Db
     /**
      * Check if current exception is on a duplicate key
      *
+     * @param SqlInterface $sql       SQL object
+     * @param Throwable    $exception Exception to check
+     *
+     * @return boolean
+     */
+    public function isDuplicateException(SqlInterface $sql, Throwable $exception): bool
+    {
+        return $sql instanceof Insert && $exception instanceof \PDOException
+            && (
+                (!$this->isPostgres() && $exception->errorInfo[1] === 1062)
+                || ($this->isPostgres() && $exception->getCode() == 23505)
+            )
+        ;
+    }
+
+    /**
+     * Check if current exception is related to a remaining foreign key
+     *
      * @param Throwable $exception Exception to check
      *
      * @return boolean
      */
-    public function isDuplicateException($exception)
+    public function isForeignKeyException(Throwable $exception): bool
     {
         return $exception instanceof \PDOException
             && (
-                (!$this->isPostgres() && $exception->getCode() == 23000)
-                || ($this->isPostgres() && $exception->getCode() == 23505)
+                (!$this->isPostgres() && in_array($exception->errorInfo[1], [1217, 1451]))
+                || ($this->isPostgres() && $exception->getCode() == 23503)
             )
         ;
     }
index fc1f40927bba8e8dcf144d0068b3f4e4d5cd6854..0899539a7f3409a22a7cf2f892b94d80c29b0ad8 100644 (file)
@@ -461,7 +461,7 @@ class MailingHistory extends History
             return true;
         } catch (Throwable $e) {
             Analog::log(
-                'An error occurend storing Mailing | ' . $e->getMessage(),
+                'An error occurred storing Mailing | ' . $e->getMessage(),
                 Analog::ERROR
             );
             throw $e;
index cd57d9bdc0bf8519d6fd2641167c7b7103174ab2..3e3d3553adb7302f4522167abf37d9ffb53246e7 100644 (file)
@@ -326,7 +326,7 @@ class Group
             if ($transaction) {
                 $zdb->connection->rollBack();
             }
-            if (!$zdb->isPostgres() && $e->getCode() == 23000 || $zdb->isPostgres() && $e->getCode() == 23503) {
+            if ($zdb->isForeignKeyException($e)) {
                 Analog::log(
                     str_replace(
                         '%group',
index 779161b2713d4f1afbd81bbeef6f4c2a4526a738..0f0764f478c527cddedb59eef309528ca9b5a66d 100644 (file)
@@ -423,7 +423,7 @@ class Members
             if ($zdb->connection->inTransaction()) {
                 $zdb->connection->rollBack();
             }
-            if ($e->getCode() == 23000) {
+            if ($zdb->isForeignKeyException($e)) {
                 Analog::log(
                     'Member still have existing dependencies in the ' .
                     'database, maybe a mailing or some content from a ' .
index 1c0ce498b3498bf961d14ea5a9551b4122fdb9eb..f5f9c346db96cdc3a8d8e940c5a0316e36c2380a 100644 (file)
@@ -1164,4 +1164,50 @@ class Members extends GaletteTestCase
         $list = $members->getArrayList($selected, ['nom_adh', 'prenom_adh']);
         $this->assertCount(4, $list);
     }
+
+    /**
+     * Test getMembersList
+     *
+     * @return void
+     */
+    public function testRemoveMembers(): void
+    {
+        $members = new \Galette\Repository\Members();
+
+        //Filter on inactive accounts
+        $filters = new \Galette\Filters\MembersList();
+        $filters->filter_account = \Galette\Repository\Members::INACTIVE_ACCOUNT;
+        $members = new \Galette\Repository\Members($filters);
+        $list = $members->getList();
+
+        $this->assertSame(1, $list->count());
+
+        $member_data = $list->current();
+        $member = new \Galette\Entity\Adherent($this->zdb, $member_data[\Galette\Entity\Adherent::PK]);
+        //var_export($member);
+
+        //add member as sender for a mailing
+        $mailhist = new \Galette\Core\MailingHistory($this->zdb, $this->login, $this->preferences);
+
+        $values = array(
+            'mailing_sender'            => $member->id,
+            'mailing_sender_name'       => 'test',
+            'mailing_sender_address'    => 'test@test.com',
+            'mailing_subject'           => $this->seed,
+            'mailing_body'              => 'a mailing',
+            'mailing_date'              => '2015-01-01 00:00:00',
+            'mailing_recipients'        => serialize([]),
+            'mailing_sent'              => true
+        );
+        $insert = $this->zdb->insert(\Galette\Core\MailingHistory::TABLE);
+        $insert->values($values);
+        $this->zdb->execute($insert);
+        $mailing_id = $this->zdb->getLastGeneratedValue($mailhist);
+
+        $this->assertFalse($members->removeMembers($member->id));
+        $this->assertSame(['Cannot remove a member who still have dependencies (mailings, ...)'], $members->getErrors());
+        //remove mailing so member can be removed
+        $this->assertTrue($mailhist->removeEntries($mailing_id, $this->history));
+        $this->assertTrue($members->removeMembers($member->id));
+    }
 }