Forum

Thread tagged as: Shop

Why does editing an address create a new one?

OK, so I go to edit an address, hit save and it has created a new record rather than editing the original one! This rather screws up my plan of keeping just one address per customer and allowing them to edit it!

Lisa Morena

Lisa Morena 1 points

  • 4 years ago
Rachel Andrew

Rachel Andrew 394 points
Perch Support

We'd need to see your code to be able to help!

OK, well I have been looking for a way to allow pass the logged in member address to the edit address form when the user shops for the first time (using this as a add address form really). I then want to show this one address next time they shop with an option to edit, so that there is only ever one address in the system. This is how I have done it. It seems to work except for the extra address being added instead of editing the existing one. I am sure I have probably got something muddled somewhere along the line as it took me a while to get my head around the whole thing!

So we start at address.php (the user is already logged in as a member at this point). I test if an address exists for the customer:

if  (empty($addresses)) {
perch_shop_edit_address_form();
} else {
perch_shop_order_address_form([
'template' => 'checkout/order_address_form.html'
]);
}

If no address, then the shop edit address form is pre-populated with their member address, but they are allowed to change it:

<div class="error"><span></span></div>
<perch:form id="address" method="post" app="perch_shop" class="address_form">
    <fieldset>
        <ol><li><perch:label for="address_1">Address: </perch:label><perch:input type="text" class="text" id="address_1" required="true" label="Address" value="<perch:members id="address" />"   /></li>
        <li><perch:label for="city">City: </perch:label><perch:input type="text" class="text" id="city" label="City" required="true" value="<perch:members id="city" />"  /></li>
        <li><perch:label for="county">County: </perch:label><perch:input type="text" class="text" id="county" required="true" label="County" value="<perch:members id="county" />" /></li>
        <li><perch:label for="postcode">Post Code: </perch:label><perch:input type="text" class="text" required="true" id="postcode" label="Post Code" value="<perch:members id="post_code" />" /></li>
         <li><perch:label for="country">Country</perch:label><perch:input <perch:input type="select" class="text select" required="true" options="United Kingdom|236, Isle of Man|106, Guernsey|91, Jersey|112" id="country" label="Country" value="<perch:members id="country" />"  /></li>
         <li><perch:label for="phone">Phone</perch:label><perch:input type="text" class="text" value="<perch:members id="phone" />" required="true" id="phone" label="Phone"  /></li>
         </ol>

</fieldset>
            <perch:input type="submit" value="Continue" class="button" />
            <perch:input type="hidden" id="first_name" value="<perch:members id="first_name" />" readonly="true" />
            <perch:input type="hidden" id="last_name" value="<perch:members id="last_name" />" readonly="true" />
            <perch:input type="hidden" id="main" value="mydefault" readonly="true" />
            <perch:input type="hidden" id="r" value="/shop/address.php" />

</perch:form>

The page refreshes on submitting (only one address is created at this point - yippee!) and shows the same as they would if there was already an address on the system so checkout/order_address_form.html looks like this:

<perch:form id="order_address" method="post" app="perch_shop">
    <perch:addresses>
    <perch:if id="main" value="mydefault">
    <div id="address-select">
                <perch:input type="hidden" id="shipping" value="<perch:address id="addressSlug" />" />
                <perch:input type="hidden" id="billing" value="<perch:address id="addressSlug" />" />
                <div class="dotted clearfix"><div class="inner clearfix"><img src="/images/top-right.gif" width="11" height="13" class="corner topleft" alt=""/><img src="/images/top-right.gif" width="11" height="13" class="corner topright" alt=""/>    
                <p><strong><perch:address id="addressFirstName" /> <perch:address id="addressLastName" /></strong><br />
                <perch:address id="address_1" /><br />
                <perch:address id="city" />
                <perch:address id="address_title" /><br>
<perch:address id="county" /><br>
<perch:address id="postcode" /><br>
<perch:address id="country_name" /></p>
<p><strong>Phone: <perch:address id="phone" /></strong></p>
<a href="/shop/address-edit.php?s=<perch:address id="addressID" />" class="anchor">Edit this address</a>
<img src="/images/top-right.gif" width="11" height="13" class="corner bottomleft" alt=""/><img src="/images/top-right.gif" width="11" height="13" class="corner bottomright" alt=""/></div></div></div>
</perch:if>
    </perch:addresses>
    <div class="payment">
        <perch:input type="hidden" id="r" />
        <perch:input type="submit" class="button" id="submit" value="Continue" />
        </div>
</perch:form>

Note that I am filtering on the 'Main' field - I was trying to find a way to filter for just the address that had been created in the previous form, but since multiples are being created on edit, it is pretty useless! Here, you will see that I have hidden the radio buttons and show just the address an edit link and a submit button. The submit should send the order address form so that the order address is now set (although I am now getting a blank page on checkout for some reason - was working before. May be just something I have made a mess of while making changes to the address set up, but that is the next issue to sort out!). If they edit an address, they go to address-edit.php:

<?php
perch_shop_edit_address_form($_GET['s'], [
'template' => 'addresses/edit-real.html']);
?>

addresses/edit-real.html:

<perch:form id="address" method="post" app="perch_shop" class="address_form">
    <fieldset>
        <ol><li><perch:label for="address_1">Address: </perch:label><perch:input type="text" class="text" id="address_1" required="true" label="Address"  /></li>
        <li><perch:label for="city">City: </perch:label><perch:input type="text" class="text" id="city" label="City" /></li>
        <li><perch:label for="county">County: </perch:label><perch:input type="text" class="text" id="county" label="County" /></li>
        <li><perch:label for="postcode">Post Code: </perch:label><perch:input type="text" class="text" id="postcode" label="Post Code" /></li>
         <li><perch:label for="country">Country</perch:label><perch:input type="select" class="text" options="<perch:shop id="country_list" />" value="GB" id="country" label="Country" /></li>
         <li><perch:label for="phone">Phone</perch:label><perch:input type="text" class="text" id="phone" label="Phone"  /></li>
         </ol>

</fieldset>
            <perch:input type="submit" value="Continue" class="button" />
            <perch:input type="hidden" id="first_name" value="<perch:members id="first_name" />" />
            <perch:input type="hidden" id="last_name" value="<perch:members id="last_name" />" />
            <perch:input type="hidden" id="main"  />
            <perch:input type="hidden" id="r" value="/shop/address.php" />

</perch:form>

This goes back to address.php again after completion. It is at this point that a whole new address seems to be added instead of editing the original one. The form is populated with the correct address as per the address ID.

So that is the whole flow of the address thing. Am I doing something wrong?

Drew McLellan

Drew McLellan 2638 points
Perch Support

perch_shop_edit_address_form() will create a new address.

If you want to edit an address, you need to pass in the ID of the address to edit, which you can get with perch_shop_customer_addresses()

perch_shop_edit_address_form(123);

Yes, I thought that is what I was doing. In address-edit.php I have:

perch_shop_edit_address_form($_GET['s'], [
'template' => 'addresses/edit-real.html']);

The 's' is passed on from the order address form where I have:

<a href="/shop/address-edit.php?s=<perch:address id="addressID" />" class="anchor">Edit this address</a>

Therefore, it is getting the addressID for the address that is shown on the address form (the correct ID according to the database). The correct address also shows as pre-populated on the edit form on address-edit.php. I just don't get why it should be creating a new one still.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Are you trying to edit an address that is already associated with an order?

I realise I forgot to show where I was getting $addresses from on address.php

 $addresses = perch_shop_customer_addresses([
'skip-template' => true,]);

No, not already associated with an order, just with that customer. This is before I have placed an order.

I know it is unlikely that someone will save their address to the shop for the first time and then edit it before placing an order, but they might do...

Hmm, OK so also when I proceed to the checkout page (after submiting the order address form, selecting billing and shipping addresses (always the same anyway)) the address gets added twice more (although only shows up on my address.php page once if I go back there)!

All I want to do is have ONE customer address. This is used for billing and shipping (they have no choice about that). The first time they order, I want the form it pre-poulated with their member address for ease of use. I then want them to be able to edit that address, but not add any new ones.

Am I going about it in completely the wrong way?

Drew McLellan

Drew McLellan 2638 points
Perch Support

Can you show me the debug output when the edit happens?

It's normal to have multiples in the database table - they get locked when an order is placed so that you can't destroy your tax audit history.

Sorry, I didn't get an email that time telling me you had replied.

On address-edit.php at the time of editing:

SELECT * FROM perch2_members_sessions WHERE sessionID='560a5239b7dbf27e57322897e036a6a41c367e62' AND sessionHttpFootprint='14e734a83aa2b75dd785af4979363931fedba4fe' AND sessionExpires>'2016-10-17 18:34:12' LIMIT 1 User is logged in [1] SELECT * FROM perch2_pages WHERE pagePath='/shop/address-edit.php' LIMIT 1 [1] SELECT * FROM perch2_shop_cart WHERE cartID=9 [1] SELECT * FROM perch2_shop_cart WHERE cartID=9 [250] SELECT country, countryID FROM perch2_shop_countries ORDER BY country ASC [25] SELECT DISTINCT settingID, settingValue FROM perch2_settings WHERE userID=0 Using template: \templates\shop\addresses\edit-real.html [1] SELECT * FROM perch2_shop_customers WHERE memberID=1 [1] SELECT * FROM perch2_shop_addresses WHERE customerID='1' AND addressID=3 [1] SELECT * FROM perch2_shop_countries WHERE countryID='236' LIMIT 1

and on address.php after editing an addres (and now seeing two addresses):

SELECT * FROM perch2_members_sessions WHERE sessionID='560a5239b7dbf27e57322897e036a6a41c367e62' AND sessionHttpFootprint='14e734a83aa2b75dd785af4979363931fedba4fe' AND sessionExpires>'2016-10-17 18:37:05' LIMIT 1
User is logged in
[1] SELECT * FROM perch2_pages WHERE pagePath='/shop/address.php' LIMIT 1
[1] SELECT * FROM perch2_shop_cart WHERE cartID=9
[1] SELECT * FROM perch2_shop_cart WHERE cartID=9
[1] SELECT * FROM perch2_shop_customers WHERE memberID=1
[2] SELECT main.* FROM perch2_shop_addresses main WHERE 1=1 AND (customerID=1) AND addressDeleted IS NULL AND orderID IS NULL ORDER BY addressTitle ASC
[25] SELECT DISTINCT settingID, settingValue FROM perch2_settings WHERE userID=0
Using template: \templates\shop\addresses\list.html
[1] SELECT * FROM perch2_shop_countries WHERE countryID='236' LIMIT 1
[1] SELECT * FROM perch2_shop_countries WHERE countryID='236' LIMIT 1
[1] SELECT * FROM perch2_shop_customers WHERE memberID=1
[2] SELECT * FROM perch2_shop_addresses WHERE customerID='1' AND orderID IS NULL
[2] Using template: \templates\shop\checkout\order_address_form.html
[1] SELECT * FROM perch2_shop_countries WHERE countryID='236' LIMIT 1
[1] SELECT * FROM perch2_shop_countries WHERE countryID='236' LIMIT 1
Drew McLellan

Drew McLellan 2638 points
Perch Support

Are either of those after the form is posted?

The second one is. The first is before...... I have the page to redirect to address.php after the form is posted. I will remove the redirection and send the debug on the address-edit.php AFTER the form is subitted

Here you go:

SELECT * FROM perch2_members_sessions WHERE sessionID='560a5239b7dbf27e57322897e036a6a41c367e62' AND sessionHttpFootprint='14e734a83aa2b75dd785af4979363931fedba4fe' AND sessionExpires>'2016-10-18 09:19:11' LIMIT 1
User is logged in
[1] SELECT * FROM perch2_pages WHERE pagePath='/shop/address-edit.php' LIMIT 1
[1] SELECT * FROM perch2_shop_cart WHERE cartID=9
[1] SELECT * FROM perch2_shop_cart WHERE cartID=9
[25] SELECT DISTINCT settingID, settingValue FROM perch2_settings WHERE userID=0
[1] SELECT * FROM perch2_shop_customers WHERE memberID=1
INSERT INTO perch2_shop_addresses(addressDynamicFields,addressCreated) VALUES('{\"address_1\":\"My new address\",\"city\":\"Chelmsford\",\"county\":\"Essex\",\"postcode\":\"CM1 234\",\"country\":\"236\",\"phone\":\"01245 123456\",\"first_name\":\"Andrea\",\"last_name\":\"Clark\",\"main\":\"mydefault\",\"r\":\"\\/shop\\/checkout.php\",\"customer\":\"1\",\"title\":\"My new address\"}','2016-10-18 08:19:11')
[1] SELECT * FROM perch2_shop_addresses WHERE addressID='6' LIMIT 1
No ids to log.
UPDATE perch2_shop_addresses SET addressDynamicFields='{\"address_1\":\"My new address\",\"city\":\"Chelmsford\",\"county\":\"Essex\",\"postcode\":\"CM1 234\",\"country\":\"236\",\"phone\":\"01245 123456\",\"first_name\":\"Andrea\",\"last_name\":\"Clark\",\"main\":\"mydefault\",\"r\":\"\\/shop\\/checkout.php\",\"customer\":\"1\",\"title\":\"My new address\"}', addressCreated='2016-10-18 08:19:11', addressTitle='My new address', addressSlug='my-new-address', addressFirstName='Andrea', addressLastName='Clark', addressLine1='My new address', customerID='1', countryID='236', addressUpdated='2016-10-18 09:19:12' WHERE addressID='6'
No ids to log.
[250] SELECT country, countryID FROM perch2_shop_countries ORDER BY country ASC
Using template: \templates\shop\addresses\edit-real.html
[1] SELECT * FROM perch2_shop_customers WHERE memberID=1
[1] SELECT * FROM perch2_shop_addresses WHERE customerID='1' AND addressID=5
[1] SELECT * FROM perch2_shop_countries WHERE countryID='236' LIMIT 1

The ID of the address I was editing was 5, but it clearly references 6 here, which is the ID of the new address it creates instead of editing 5

Drew McLellan

Drew McLellan 2638 points
Perch Support

Are you passing the address ID through in the edit form?

<perch:input type="hidden" id="addressID" />

No! That'd be it then! Thank you for pointing out my utter stupidity! Too many late nights me thinks...

So now it is working, do you think this is a good way of going about what I am trying to do in general then? If I really must make the member keep two addresses (one for member, one for shop) I want it to be as simple as possible by pre-populating the initial address form and then keeping just the one address and allowing them to edit it. This is the only way I coudl get my head around doing that - is it how you'd do it?

Drew McLellan

Drew McLellan 2638 points
Perch Support

Do you need to keep an address against the Member if you keep it in the Shop?

Yes as the whole member thing needs to come first really. The shop is more of an extension to the membership allowing them to place an order. We need to easily access all the member's data including the address in one place rather than having to go to the shop app just for their address.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Ok, so I think that's your answer.