From ad1b9d080460cadbe6ee0eda0ca9c85cef9d97df Mon Sep 17 00:00:00 2001
From: mildis <me@mildis.org>
Date: Wed, 14 Apr 2021 19:38:00 +0200
Subject: [PATCH] add logic to update an address

Currently address update relies on SQL REPLACE
but AddressCreateCommand is not using addresse.id
to achieve this.

This patch adds AddressUpdateCommand and update logic
so updating an adresse should be doable from the
user's web page
---
 app/controller/perso.php                      | 21 ++++++
 app/view/user/perso.html                      |  9 ++-
 src/LQDN/Command/AddressUpdateCommand.php     | 74 +++++++++++++++++++
 src/LQDN/Handler/AddressHandler.php           | 35 +++++++++
 .../functional/Handler/AddressHandlerTest.php | 24 ++++++
 5 files changed, 162 insertions(+), 1 deletion(-)
 create mode 100644 src/LQDN/Command/AddressUpdateCommand.php

diff --git a/app/controller/perso.php b/app/controller/perso.php
index f5d3410..66cc6ed 100644
--- a/app/controller/perso.php
+++ b/app/controller/perso.php
@@ -287,6 +287,27 @@ class Perso extends Controller
             }
             $f3->push('SESSION.message', _("Adresse ajoutée à votre profil"));
             break;
+        case 'UPDATE':
+            try {
+                $f3->get('container')['command_handler']->handle(
+                    new AddressUpdateCommand(
+                        \Utils::asl($f3->get('id')),
+                        \Utils::asl($f3->get('SESSION.id')),
+                        \Utils::asl($f3->get('nom')),
+                        \Utils::asl($f3->get('adresse')),
+                        \Utils::asl($f3->get('adresse2')),
+                        \Utils::asl($f3->get('codepostal')),
+                        \Utils::asl($f3->get('ville')),
+                        \Utils::asl($f3->get('pays')),
+                        \Utils::asl($f3->get('state'))
+                    )
+                );
+            } catch (AddressAlreadyExistsException $e) {
+                $f3->set("error", _("Cette adresse existe déjà."));
+                $f3->error('403');
+            }
+            $f3->push('SESSION.message', _("Adresse du profil modifiée."));
+            break;
         case 'DELETE':
             try {
                 $f3->get('container')['command_handler']->handle(
diff --git a/app/view/user/perso.html b/app/view/user/perso.html
index d5d3aa7..524f8e4 100644
--- a/app/view/user/perso.html
+++ b/app/view/user/perso.html
@@ -79,8 +79,15 @@
                             <h3>{{ _("Renseigner votre adresse.")}}</h3>
                             <form method="POST" action="{{ 'adresses' | alias }}" id="create-adress-form">
                                 <input type="hidden" name="csrf" value="{{ @CSRF }}" />
-                                <input type="hidden" name="action" value="ADD" />
+                                <check if="{{ @adresse }}">
+                                <true>
+                                <input type="hidden" name="action" value="UPDATE" />
                                 <input type="hidden" name="id" value="{{ @@adresse.id }}" />
+                                </true>
+                                <false>
+                                <input type="hidden" name="action" value="ADD" />
+                                </false>
+                                </check>
                                 <div class="form-group">
                                     <label for="nom">{{ _("Destinataire") }}</label>
                                     <input type="text" class="form-control" name="nom" value="{{ @@adresse.nom }}">
diff --git a/src/LQDN/Command/AddressUpdateCommand.php b/src/LQDN/Command/AddressUpdateCommand.php
new file mode 100644
index 0000000..e094fd3
--- /dev/null
+++ b/src/LQDN/Command/AddressUpdateCommand.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace LQDN\Command;
+
+class AddressUpdateCommand
+{
+    private $addressId;
+    private $userId;
+    private $name;
+    private $address;
+    private $address2;
+    private $postalCode;
+    private $city;
+    private $country;
+    private $state;
+
+    public function __construct($addressId, $userId, $name, $address, $address2, $postalCode, $city, $country, $state)
+    {
+        $this->addressId = $addressId;
+        $this->userId = $userId;
+        $this->name = $name;
+        $this->address = $address;
+        $this->address2 = $address2;
+        $this->postalCode = $postalCode;
+        $this->city = $city;
+        $this->country = $country;
+        $this->state = $state;
+    }
+
+    public function getAddressId()
+    {
+        return $this->addressId;
+    }
+
+    public function getUserId()
+    {
+        return $this->userId;
+    }
+
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    public function getAddress()
+    {
+        return $this->address;
+    }
+
+    public function getAddress2()
+    {
+        return $this->address2;
+    }
+
+    public function getPostalCode()
+    {
+        return $this->postalCode;
+    }
+
+    public function getCity()
+    {
+        return $this->city;
+    }
+
+    public function getCountry()
+    {
+        return $this->country;
+    }
+
+    public function getState()
+    {
+        return $this->state;
+    }
+}
diff --git a/src/LQDN/Handler/AddressHandler.php b/src/LQDN/Handler/AddressHandler.php
index cbc247f..96eb32e 100644
--- a/src/LQDN/Handler/AddressHandler.php
+++ b/src/LQDN/Handler/AddressHandler.php
@@ -63,6 +63,41 @@ EOF;
         $stmt->execute();
     }
 
+    /**
+     * Update an address.
+     *
+     * @param AddressUpdateCommand $command
+     */
+    public function handleAddressUpdateCommand(AddressUpdateCommand $command)
+    {
+        $addressId = $command->getAddressId();
+        $userId = $command->getUserId();
+
+        // Let's check if the address is used
+        if ($this->addressUsed($addressId) == true) {
+            // The address is used somehow
+            throw new AddressUsedException();
+        };
+
+        $query =<<<EOF
+UPDATE adresses
+SET nom = :name, adresse = :address, adresse2 = :address2, codepostal = :postal_code, ville = :city, etat = :state, pays = :country
+WHERE id = :id and user_id = :user_id
+EOF;
+
+        $stmt = $this->connection->prepare($query);
+        $stmt->bindValue('id', $command->getAddressId());
+        $stmt->bindValue('user_id', $command->getUserId());
+        $stmt->bindValue('name', $command->getName());
+        $stmt->bindValue('address', $command->getAddress());
+        $stmt->bindValue('address2', $command->getAddress2());
+        $stmt->bindValue('postal_code', $command->getPostalCode());
+        $stmt->bindValue('city', $command->getCity());
+        $stmt->bindValue('state', $command->getState());
+        $stmt->bindValue('country', $command->getCountry());
+        $stmt->execute();
+    }
+
     /**
      * Check if an address already exists.
      *
diff --git a/tests/functional/Handler/AddressHandlerTest.php b/tests/functional/Handler/AddressHandlerTest.php
index 8155816..a5798a5 100644
--- a/tests/functional/Handler/AddressHandlerTest.php
+++ b/tests/functional/Handler/AddressHandlerTest.php
@@ -61,6 +61,30 @@ class AddressHandlerTest extends FunctionalTest
         $this->assertSame($expectedAddress, $latestAddress);
     }
 
+    public function testAddressUpdate()
+    {
+        $this->assertTrue($this->addressExists(1));
+
+        $latestAddress = $this->getLatestAddress();
+
+        $this->container['command_handler']->handle(new AddressUpdateCommand($latestAddress['id'], 1, 'LQDN', '115 rue de Ménilmontant', '', 75020, 'Paris', 'France', 'IDF'));
+
+        $expectedAddress = [
+            'id' => $latestAddress['id'],
+            'user_id' => '1',
+            'nom' => 'LQDN',
+            'adresse' => '115 rue de Ménilmontant',
+            'adresse2' => '',
+            'codepostal' => '75020',
+            'ville' => 'Paris',
+            'pays' => 'France',
+            'etat' => 'IDF',
+        ];
+
+        $updatedAddress = $this->getLatestAddress();
+        $this->assertSame($expectedAddress, $updatedAddress);
+    }
+
     /**
      * Check if an address exists in DB.
      *
-- 
GitLab