]> git.agnieray.net Git - galette.git/commitdiff
Disable events from mass changes; closes #1733
authorJohan Cwiklinski <johan@x-tnd.be>
Thu, 22 Feb 2024 20:56:01 +0000 (21:56 +0100)
committerJohan Cwiklinski <johan@x-tnd.be>
Fri, 1 Mar 2024 07:21:10 +0000 (08:21 +0100)
galette/lib/Galette/Controllers/Crud/ContributionsController.php
galette/lib/Galette/Controllers/Crud/MembersController.php
galette/lib/Galette/Entity/Adherent.php
galette/lib/Galette/Entity/Contribution.php
galette/lib/Galette/Features/HasEvent.php [new file with mode: 0644]
tests/Galette/Features/tests/units/HasEvent.php [new file with mode: 0644]

index 146e37fe9addf2574787d41c5b3ac0b64317f6bc..ebee1834eb064bbc4f0be95c21d57fe0960c5c1b 100644 (file)
@@ -337,6 +337,7 @@ class ContributionsController extends CrudController
         foreach ($members_ids as $member_id) {
             $post[Adherent::PK] = (int)$member_id;
             $contrib = new Contribution($this->zdb, $this->login);
+            $contrib->disableEvents();
 
             // regular fields
             $valid = $contrib->check($post, $contrib->getRequired(), $disabled);
index d9b1fcaf3f7d1dabb1e46f7f4b2d39936bf3e871..6891ee25da4d6b4592e907260358c826e5867ef9 100644 (file)
@@ -1307,7 +1307,9 @@ class MembersController extends CrudController
                         && !$this->login->isStaff()
                         && $this->login->isGroupManager();
                     $member = new Adherent($this->zdb);
-                    $member->disableAllDeps();
+                    $member
+                        ->disableAllDeps()
+                        ->disableEvents();
                     if ($is_manager) {
                         $member->enableDep('groups');
                     }
index 9b844fc231ac148872596412f6bb271251f5e888..e6d67b4d94282f039c845efa3ac25c9182bf9686 100644 (file)
@@ -38,6 +38,7 @@ namespace Galette\Entity;
 
 use ArrayObject;
 use Galette\Events\GaletteEvent;
+use Galette\Features\HasEvent;
 use Galette\Features\Socials;
 use Throwable;
 use Analog\Analog;
@@ -126,6 +127,7 @@ class Adherent
 {
     use Dynamics;
     use Socials;
+    use HasEvent;
 
     public const TABLE = 'adherents';
     public const PK = 'id_adh';
@@ -237,6 +239,12 @@ class Adherent
             }
         }
 
+        $this
+            ->withAddEvent()
+            ->withEditEvent()
+            ->withoutDeleteEvent()
+            ->activateEvents();
+
         if ($args == null || is_int($args)) {
             if (is_int($args) && $args > 0) {
                 $this->load($args);
@@ -1569,7 +1577,7 @@ class Adherent
                         );
                     }
 
-                    $event = 'member.add';
+                    $event = $this->getAddEventName();
                 } else {
                     $hist->add(_T("Fail to add new member."));
                     throw new \Exception(
@@ -1605,7 +1613,7 @@ class Adherent
                         $this->sname
                     );
                 }
-                $event = 'member.edit';
+                $event = $this->getEditEventName();
             }
 
             //dynamic fields
@@ -1613,7 +1621,7 @@ class Adherent
             $this->storeSocials($this->id);
 
             //send event at the end of process, once all has been stored
-            if ($event !== null) {
+            if ($event !== null && $this->areEventsEnabled()) {
                 $emitter->dispatch(new GaletteEvent($event, $this));
             }
             return true;
@@ -2267,4 +2275,14 @@ class Adherent
         $this->loadParent();
         return $this;
     }
+
+    /**
+     * Get prefix for events
+     *
+     * @return string
+     */
+    protected function getEventsPrefix(): string
+    {
+        return 'member';
+    }
 }
index f8cc8bd0db1e93ca8cf37ee7a0a2e1a896b65759..3457da44e01dc8437c3eeeb0d82943f3376dc18a 100644 (file)
@@ -40,6 +40,7 @@ namespace Galette\Entity;
 use ArrayObject;
 use DateTime;
 use Galette\Events\GaletteEvent;
+use Galette\Features\HasEvent;
 use Throwable;
 use Analog\Analog;
 use Laminas\Db\Sql\Expression;
@@ -85,6 +86,7 @@ use Galette\Features\Dynamics;
 class Contribution
 {
     use Dynamics;
+    use HasEvent;
 
     public const TABLE = 'cotisations';
     public const PK = 'id_cotis';
@@ -135,6 +137,12 @@ class Contribution
         global $preferences;
         $this->_payment_type = (int)$preferences->pref_default_paymenttype;
 
+        $this
+            ->withAddEvent()
+            ->withEditEvent()
+            ->withoutDeleteEvent()
+            ->activateEvents();
+
         /*
          * Fields configuration. Each field is an array and must reflect:
          * array(
@@ -683,7 +691,7 @@ class Contribution
                         _T("Contribution added"),
                         Adherent::getSName($this->zdb, $this->_member)
                     );
-                    $event = 'contribution.add';
+                    $event = $this->getAddEventName();
                 } else {
                     $hist->add(_T("Fail to add new contribution."));
                     throw new \Exception(
@@ -705,7 +713,7 @@ class Contribution
                     );
                 }
 
-                $event = 'contribution.edit';
+                $event = $this->getEditEventName();
             }
             //update deadline
             if ($this->isFee()) {
@@ -719,7 +727,7 @@ class Contribution
             $this->_orig_amount = $this->_amount;
 
             //send event at the end of process, once all has been stored
-            if ($event !== null) {
+            if ($event !== null && $this->areEventsEnabled()) {
                 $emitter->dispatch(new GaletteEvent($event, $this));
             }
 
@@ -1505,4 +1513,14 @@ class Contribution
 
         return false;
     }
+
+    /**
+     * Get prefix for events
+     *
+     * @return string
+     */
+    protected function getEventsPrefix(): string
+    {
+        return 'contribution';
+    }
 }
diff --git a/galette/lib/Galette/Features/HasEvent.php b/galette/lib/Galette/Features/HasEvent.php
new file mode 100644 (file)
index 0000000..b1d0765
--- /dev/null
@@ -0,0 +1,237 @@
+<?php
+
+/**
+ * Has events trait
+ *
+ * PHP version 5
+ *
+ * Copyright © 2024 The Galette Team
+ *
+ * This file is part of Galette (http://galette.tuxfamily.org).
+ *
+ * Galette is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Galette is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Galette. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  Features
+ * @package   Galette
+ *
+ * @author    Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2024 The Galette Team
+ * @license   https://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link      https://galette.eu
+ */
+
+namespace Galette\Features;
+
+/**
+ * Has events trait
+ *
+ * @category  Features
+ * @name      HasEvents
+ * @package   Galette
+ * @author    Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2024 The Galette Team
+ * @license   https://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link      https://galette.eu
+ */
+
+trait HasEvent
+{
+    private bool $has_add_event = false;
+    private bool $has_edit_event = false;
+    private bool $has_delete_event = false;
+    protected bool $events_active = true;
+
+    /**
+     * Get prefix for events
+     *
+     * @return string
+     */
+    abstract protected function getEventsPrefix(): string;
+
+    /**
+     * Activate events
+     *
+     * @return self
+     */
+    public function activateEvents(): self
+    {
+        $this->events_active = true;
+        return $this;
+    }
+
+    /**
+     * Disable events
+     *
+     * @return self
+     */
+    public function disableEvents(): self
+    {
+        $this->events_active = false;
+        return $this;
+    }
+
+    /**
+     * Are events enabled
+     *
+     * @return bool
+     */
+    public function areEventsEnabled(): bool
+    {
+        return $this->events_active;
+    }
+
+    /**
+     * Activate add event
+     *
+     * @return self
+     */
+    public function withAddEvent(): self
+    {
+        $this->has_add_event = true;
+        return $this;
+    }
+
+    /**
+     * Disable add event
+     *
+     * @return self
+     */
+    public function withoutAddEvent(): self
+    {
+        $this->has_add_event = false;
+        return $this;
+    }
+
+    /**
+     * Get add event name
+     *
+     * @return ?string
+     */
+    public function getAddEventName(): ?string
+    {
+        if (!$this->hasAddEvent()) {
+            return null;
+        }
+        return sprintf(
+            '%1$s.add',
+            $this->getEventsPrefix()
+        );
+    }
+
+    /**
+     * Has add event
+     *
+     * @return bool
+     */
+    public function hasAddEvent(): bool
+    {
+        return $this->areEventsEnabled() && $this->has_add_event;
+    }
+
+    /**
+     * Activate edit event
+     *
+     * @return self
+     */
+    public function withEditEvent(): self
+    {
+        $this->has_edit_event = true;
+        return $this;
+    }
+
+    /**
+     * Disable edit event
+     *
+     * @return self
+     */
+    public function withoutEditEvent(): self
+    {
+        $this->has_edit_event = false;
+        return $this;
+    }
+
+    /**
+     * Get edit event name
+     *
+     * @return ?string
+     */
+    public function getEditEventName(): ?string
+    {
+        if (!$this->hasEditEvent()) {
+            return null;
+        }
+        return sprintf(
+            '%1$s.edit',
+            $this->getEventsPrefix()
+        );
+    }
+
+    /**
+     * Has edit event
+     *
+     * @return bool
+     */
+    public function hasEditEvent(): bool
+    {
+        return $this->areEventsEnabled() && $this->has_edit_event;
+    }
+
+    /**
+     * Activate add event
+     *
+     * @return self
+     */
+    public function withDeleteEvent(): self
+    {
+        $this->has_delete_event = true;
+        return $this;
+    }
+
+    /**
+     * Disable delete event
+     *
+     * @return self
+     */
+    public function withoutDeleteEvent(): self
+    {
+        $this->has_delete_event = false;
+        return $this;
+    }
+
+    /**
+     * Get edit event name
+     *
+     * @return ?string
+     */
+    public function getDeleteEventName(): ?string
+    {
+        if (!$this->hasDeleteEvent()) {
+            return null;
+        }
+        return sprintf(
+            '%1$s.delete',
+            $this->getEventsPrefix()
+        );
+    }
+
+    /**
+     * Has delete event
+     *
+     * @return bool
+     */
+    public function hasDeleteEvent(): bool
+    {
+        return $this->areEventsEnabled() && $this->has_delete_event;
+    }
+}
diff --git a/tests/Galette/Features/tests/units/HasEvent.php b/tests/Galette/Features/tests/units/HasEvent.php
new file mode 100644 (file)
index 0000000..2f17592
--- /dev/null
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * HasEvents tests
+ *
+ * PHP version 5
+ *
+ * Copyright © 2024 The Galette Team
+ *
+ * This file is part of Galette (http://galette.tuxfamily.org).
+ *
+ * Galette is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Galette is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Galette. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  Features
+ * @package   GaletteTests
+ *
+ * @author    Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2024 The Galette Team
+ * @license   https://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link      https://galette.eu
+ */
+
+namespace Galette\Entity\test\units;
+
+use Galette\GaletteTestCase;
+
+/**
+ * HasEvent tests class
+ *
+ * @category  Features
+ * @name      HasEvents
+ * @package   GaletteTests
+ * @author    Johan Cwiklinski <johan@x-tnd.be>
+ * @copyright 2024 The Galette Team
+ * @license   https://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
+ * @link      https://galette.eu
+ */
+class HasEvent extends GaletteTestCase
+{
+    protected int $seed = 20240223092214;
+
+    /**
+     * Test HasEvent capacities
+     *
+     * @return void
+     */
+    public function testCapacities(): void
+    {
+        $this->adh = new \Galette\Entity\Adherent($this->zdb);
+
+        //per default, add and edit events are active on contributions
+        $contrib = new \Galette\Entity\Contribution($this->zdb, $this->login);
+        $this->assertTrue($contrib->areEventsEnabled());
+        $this->assertTrue($contrib->hasAddEvent());
+        $this->assertTrue($contrib->hasEditEvent());
+        $this->assertFalse($contrib->hasDeleteEvent());
+        $this->assertEquals('contribution.add', $contrib->getAddEventName());
+        $this->assertEquals('contribution.edit', $contrib->getEditEventName());
+        $this->assertNull($contrib->getDeleteEventName());
+
+        //per default, add and edit events are active on members
+        $this->assertTrue($this->adh->areEventsEnabled());
+        $this->assertTrue($this->adh->hasAddEvent());
+        $this->assertTrue($this->adh->hasEditEvent());
+        $this->assertFalse($this->adh->hasDeleteEvent());
+        $this->assertEquals('member.add', $this->adh->getAddEventName());
+        $this->assertEquals('member.edit', $this->adh->getEditEventName());
+        $this->assertNull($this->adh->getDeleteEventName());
+
+        //disable add event
+        $this->adh->withoutAddEvent();
+        $this->assertFalse($this->adh->hasAddEvent());
+        $this->assertNull($this->adh->getAddEventName());
+        $this->assertTrue($this->adh->hasEditEvent());
+        //enable add event
+        $this->adh->withAddEvent();
+        $this->assertTrue($this->adh->hasAddEvent());
+
+        //disable edit event
+        $this->adh->withoutEditEvent();
+        $this->assertTrue($this->adh->hasAddEvent());
+        $this->assertFalse($this->adh->hasEditEvent());
+        $this->assertNull($this->adh->getEditEventName());
+        //enable edit event
+        $this->adh->withEditEvent();
+        $this->assertTrue($this->adh->hasEditEvent());
+
+        //enable delete event
+        $this->adh->withDeleteEvent();
+        $this->assertTrue($this->adh->hasDeleteEvent());
+        $this->assertEquals('member.delete', $this->adh->getDeleteEventName());
+        //disable delete event
+        $this->adh->withoutDeleteEvent();
+        $this->assertFalse($this->adh->hasDeleteEvent());
+
+        // disable all events
+        $this->adh->disableEvents();
+        $this->assertFalse($this->adh->areEventsEnabled());
+        $this->assertFalse($this->adh->hasAddEvent());
+        $this->assertFalse($this->adh->hasEditEvent());
+        $this->assertFalse($this->adh->hasDeleteEvent());
+        $this->assertNull($this->adh->getAddEventName());
+        $this->assertNull($this->adh->getEditEventName());
+        $this->assertNull($this->adh->getDeleteEventName());
+
+        //reactivate events
+        $this->adh->activateEvents();
+        $this->assertTrue($this->adh->areEventsEnabled());
+        $this->assertTrue($this->adh->hasAddEvent());
+        $this->assertTrue($this->adh->hasEditEvent());
+        $this->assertFalse($this->adh->hasDeleteEvent());
+    }
+}