User Account Features [ 248 ] Changing password The process for allowing a customer to change their password should be relatively simple: 1. The customer should enter their current password. 2. The customer should enter their new password. 3. The customer should enter their new password again. 4. We should then check that their current password is valid. 5. Then we should check that their new password and their conrmation of this new password are the same. 6. We should then hash the new password and update the user's password in the database to this hash. Let's look at the code for processing this. (Steps 1 to 3 are user actions, steps 4 to 6 are system actions, which we must provide in our code.) $oldPassword = md5( $_POST['old_password'] ); // check their new password is confirmed We compare the password entered in the password box, with the password they entered in the conrmation box, to ensure they match—if they don't and we change the password to one of them, the customer may not know what the corrected password is—as it would seem they made a mistake entering in one of the password boxes. This is essentially a precaution for the customer's benet. if( $_POST['new_password'] == $_POST['confirm_newpassword'] ) { $uid = $this->registry->getObject('authenticate')->getUserID(); $checkPwdSQL = "SELECT * FROM users WHERE ID={$uid} AND password='{$oldPassword}'"; $this->registry->getObject('db')->executeQuery( $checkPwdSQL ); // check their old password is validpassword is valid is valid As it is possible that the customer left their account logged in, and someone else could be at their computer trying to change their password, we need to conrm that their existing password was entered, verifying it is the customer requesting the change. if( $this->registry->getObject('db')->numRows() == 1 ) { $changes = array(); $changes['password'] = md5( $_POST['new_password'] ); // update their current password to the new password This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Download at Wow! eBook Chapter 12 [ 249 ] We then update the database to save the customer's new password. $this->registry->getObject('db')->updateRecords( 'users', $changes, 'ID=' . $uid ); // output success message here } else { // do our error output here } } else { // error output } Changing default delivery address Allowing customers to change their default delivery address should be very straightforward; we need to check if they submitted some changes, sanitize the data, and update their details. private function saveChangesToAccount() { // default delivery address $changes = array(); // We set each array element to be part of the customer's delivery // address, and set the value to the one the customer is // submitting. $changes['default_shipping_name'] = $this->registry-> getObject('db')-> sanitizeData( $_POST['default_shipping_name'] ); $changes['default_shipping_address'] = $this->registry-> getObject('db')-> sanitizeData( $_POST['default_shipping_address'] ); $changes['default_shipping_address2'] = $this->registry-> getObject('db')-> sanitizeData( $_POST['default_shipping_address2'] ); $changes['default_shipping_city'] = $this->registry-> getObject('db')-> sanitizeData( $_POST['default_shipping_city'] ); $changes['default_shipping_postcode'] = $this->registry-> getObject('db')-> sanitizeData( $_POST['default_shipping_postcode'] ); $changes['default_shipping_country'] = $this->registry-> getObject('db')-> This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 User Account Features [ 250 ] sanitizeData( $_POST['default_shipping_country'] ); // We then update their delivery address, by making changes to the // users_extra table. $this->registry->getObject('db')->updateRecords( 'users_extra', $changes, 'ID=' . $this->registry->getObject('authenticate')->getUserID() ); // We then update the users table, to update the customer's e-mail // address. // e-mail address // The format of the e-mail address should be checked ideally $changes = array(); $changes['email'] = $this->registry->getObject('db')-> sanitizeData( $_POST['email'] ); $this->registry->getObject('db')->updateRecords( 'users', $changes, 'ID=' . $this->registry-> getObject('authenticate')->getUserID() ); $this->registry->redirectUser( 'useraccount', 'Account details changed', 'Your account details have been saved', $admin = false ); } Viewing orders The orders section of a customer's account area should be broken into two areas: List of orders, so the customer can select the order they wish to see in more detail Viewing order-specic details Listing orders To list a customer's order, we simply need a single query to lookup their orders and their status, which we can then cache and send to the template. Within the list of orders, we would want to display the following information: Order ID or reference The total cost of the order The status of the order The date the order was placed We may also wish to display the date the order was last updated, which could indicate when the order was dispatched, or cancelled, or payment was processed • • • • • • • This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Chapter 12 [ 251 ] Query The following query would allow us to list all of the user's orders, detailing the time the order was placed, the ID, the cost of products, the cost of shipping, and the status of the order: "SELECT os.name AS status_name, o.ID AS order_id, (o.products_cost + o.shipping_cost) AS cost, DATE_FORMAT(o.timestamp, '%D %b %Y') AS order_placed FROM orders o, order_statuses os WHERE os.ID=o.status AND o.user_id=" . $this->registry-> getObject('authenticate')->getUserID() Viewing an order For viewing an order, we should create a model to encapsulate all of the data for the order; this should also make things easier for us in the next chapter when we create our administration interface. Order model Our order model needs to allow us to access the following information: The customer The delivery address The items in the order The total cost of the order The shipping cost of the order If a discount voucher was used The status of the order The date the order was placed The model requires two queries to get this data: the rst to get the order data itself, and the second to get the products in the order.second to get the products in the order. to get the products in the order. Query for order details This simple query needs to get details stored in the orders table, as well as the statusquery needs to get details stored in the orders table, as well as the status needs to get details stored in the orders table, as well as the status of the order, the payment method, and the shipping method: $sql = "SELECT o.timestamp, o.user_id, o.comment, o.delivery_comment, o.shipping_name, o.shipping_address, o.shipping_address2, o.shipping_city, o.shipping_postcode, o.shipping_country, o.products_cost, o.shipping_cost, o.voucher_code, os.name • • • • • • • • This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 User Account Features [ 252 ] AS order_stauts, p.name AS payment_method, s.name AS shipping_method " . "FROM orders o, payment_methods p, order_statuses os, shipping_methods s " ."WHERE o.ID={$id} AND os.ID=o.status AND s.ID=o.shipping_method AND p.ID=o.payment_method " ."LIMIT 1"; Once the query has been executed and if there is a result, then we can set the model to valid, and populate its properties with data from the database. If no records are found, we must set the validity of the model to false. $this->registry->getObject('db')->executeQuery( $sql ); if( $this->registry->getObject('db')->numRows() > 0 ) { $this->valid = true; $orderData = $this->registry->getObject('db')->getRows(); $this->id = $id; $this->status = $orderData['status']; $this->created = $orderData['timestamp']; $this->deliveryAddress = array( $orderData['shipping_name'], $orderData['shipping_address'], $orderData['shipping_address2'], $orderData['shipping_city'], $orderData['shipping_postcode'], $orderData['shipping_country'] ); $this->productsCost = $orderData['products_cost']; $this->shippingCost = $orderData['shipping_cost']; $this->orderCost = $this->productsCost + $this->shippingCost; $this->shippingMethod = $orderData['shipping_method']; $this->paymentMethod = $orderData['payment_method']; $this->user = $orderData['user_id']; $this->comment = $orderData['comment']; $this->deliveryNote = $orderData['delivery_comment']; // items // items query to go here } else { $this->valid = false; } This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 . licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 User Account Features [ 250 ] sanitizeData( $_POST['default_shipping_country'] ); . and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Chapter 12 [ 251 ] Query The following query would allow us to list all of the user's. licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 User Account Features [ 252 ] AS order_stauts, p.name AS payment_method, s.name AS shipping_method