【Ecshop】修改处理用户购物车的行为
Ecshop v2.7.3的购物车处理方面在现在看来有比较反用户体验的设计:
- 用户未登录时加入购物车的商品,在用户登录后会被清空而不是加入到登录用户的购物车中;
- 用户登录后加入购物车的商品,在退出后会被清空。
这两种设计在现在看来简直不可理喻,对用户极不友好,作为一个以流量至上的商城,这样的设计会导致客户的流失。
查看源码才发现,ecshop是以session_id作为保存购物车商品的依据,而不是用户id。个人认为这样的设计是由于其以下单为主,用户有没有注册都可以直接下单,这样就导致其整套逻辑以"会话”为主体。
修改ecshop购物车行为,使其以客户为主,具体设计是:
- 用户登录后加入购物车的商品,退出后依然保留;
- 用户未登录时加入购物车的商品:
- 如果用户登录,则合并到客户的购物车中;
- 如果未登录即关闭,则保存到cookie中一段时间(ecshop本身已实现)
策略:
1.登录前用session_id,登录后用user_id查看,操作购物车数据;
2.用户登录后,更新合并购物车数据;
3.用户登出后,依然有无主商品的话,删除。
lib_main.php添加。
1 /** 2 * 选择购物车商品的获取条件 3 * Desc: 如果已登录,返回user_id条件,否则返回session_id条件 4 * @access public 5 * @return where condition 6 */ 7 function rec_select() 8 { 9 return (isset($_SESSION['user_id'])&&intval($_SESSION['user_id'])>0)?"user_id= ".intval($_SESSION['user_id'])." ":"session_id = '" . SESS_ID . "' "; 10 } 11 12 /** 13 * 更新购物车中的商品 14 * Desc: 如果用户已登录且其在未登录时将商品加入了购物车,那么将未登录时的购物车与用户之前的购物车商品合并 15 * @access public 16 * @return boolean 17 */ 18 function update_user_cart() 19 { 20 if(!isset($_SESSION['user_id'])) 21 return FALSE; 22 23 /*查看是否有未登录时加入购物车的商品*/ 24 $sql = "SELECT *, IF(parent_id, parent_id, goods_id) AS pid " . 25 " FROM " . $GLOBALS['ecs']->table('cart') . " " . 26 " WHERE session_id = '" . SESS_ID . "' AND user_id=0 AND rec_type = '" . CART_GENERAL_GOODS . "'" . 27 " ORDER BY pid, parent_id"; 28 $res = $GLOBALS['db']->query($sql); 29 30 $_uid=intval($_SESSION['user_id']); 31 32 while ($row = $GLOBALS['db']->fetchRow($res)) 33 { 34 if($_uid>0) 35 { 36 /* 检查该商品是否已经存在在购物车中 */ 37 $sql="SELECT * FROM {$GLOBALS['ecs']->table('cart')} WHERE user_id={$_uid} AND goods_id={$row['goods_id']} AND rec_type = '" . CART_GENERAL_GOODS."' 38 AND goods_attr='{$row['goods_attr']}' 39 AND goods_attr_id={$row['goods_attr_id']} 40 AND product_id={$row['product_id']} 41 AND parent_id={$row['parent_id']} 42 AND is_gift={$row['is_gift']} 43 AND is_shipping={$row['is_shipping']} 44 "; 45 $_one=$GLOBALS['db']->getOne($sql); 46 47 if(!empty($_one)) 48 { 49 $goods_number=$_one['goods_number']+$row['goods_number']; 50 $sql="UPDATE {$GLOBALS['ecs']->table('cart')} SET goods_number = {$goods_number} WHERE rec_id = {$_one['rec_id']}"; 51 $GLOBALS['db']->query($sql); 52 53 $sql="DELETE FROM {$GLOBALS['ecs']->table('cart')} WHERE rec_id = {$row['rec_id']}"; 54 $GLOBALS['db']->query($sql); 55 } 56 else 57 { 58 $sql="UPDATE {$GLOBALS['ecs']->table('cart')} SET user_id = {$_uid} WHERE rec_id = {$row['rec_id']}"; 59 $GLOBALS['db']->query($sql); 60 } 61 62 } 63 } 64 return TRUE; 65 }
cls_session.php修改函数
function destroy_session() { $GLOBALS['_SESSION'] = array(); setcookie($this->session_name, $this->session_id, 1, $this->session_cookie_path, $this->session_cookie_domain, $this->session_cookie_secure); /* ECSHOP 鑷?畾涔夋墽琛岄儴鍒 */ /* if (!empty($GLOBALS['ecs'])) { $this->db->query('DELETE FROM ' . $GLOBALS['ecs']->table('cart') . " WHERE session_id = '$this->session_id'"); } */ /*修改:只删除没有用户的购物车*/ if (!empty($GLOBALS['ecs'])) { $this->db->query('DELETE FROM ' . $GLOBALS['ecs']->table('cart') . " WHERE session_id = '$this->session_id' AND user_id=0"); } /* ECSHOP 鑷?畾涔夋墽琛岄儴鍒 */ $this->db->query('DELETE FROM ' . $this->session_data_table . " WHERE sesskey = '" . $this->session_id . "' LIMIT 1"); return $this->db->query('DELETE FROM ' . $this->session_table . " WHERE sesskey = '" . $this->session_id . "' LIMIT 1"); }
flow.php 在act=login,已登录的处理函数后;act=add_to_cart 加入购物车后,user.php action=act_login登录后加上
1 update_user_info(); //更新用户信息 2 /*如果用户已登录且其在未登录时将商品加入了购物车,那么将未登录时的购物车与用户之前的购物车商品合并*/ 3 update_user_cart();//新加上 4 recalculate_price(); // 重新计算购物车中的商品价格
flow.php , lib_insert.php,lib_main.php,lib_order.php , lib_transaction.php ,order.php 等内容中的 session_id='".SESS_ID."'"改为 rec_select();
测试看看。