opencart 注册流程简化 & 订单流程简化
【扯淡篇】
opencart一个电商应用的利器,PHP程序员 JAVA程序员 .NET程序员上手开发学习成本较低,良好的MVC模式,思路清晰的国际化处理,完美的商品管理方法,给开发广大开发人员带来了众多的福音。美中不足有几点:
- 注册流程复杂,强烈需要瘦身
- 订单流程复杂,强烈需要瘦身
- 老外是买东西缴税,我们是买东西要发票
- 中文的开发文档,汉化插件不多
【解决问题-1:注册流程简化】
opencart的注册需要完成注册人的地址,公司,公司编码,还有传真这些奇葩的字段,这些字段让亲们多么呕吐啊!so... 杀之! style='display:none' 样式表,这美工的橡皮才帮程序员解决注册的难题啦~!
打开opencart/catalog/view/theme/default/template/account/register.tpl
让我们尽情的display:none 首先是干掉fax!
<tr style='display:none'>
<td><?php echo $entry_fax; ?></td>
<td><input type="text" name="fax" value="<?php echo $fax; ?>" /></td>
</tr>
这个是方法1,方法2:用html的隐藏表单域解决问题
<input type="text" name="fax" value="<?php echo $fax; ?>" />
<!-- 干掉tr td 替换成 -->
<input type="hidden" name="fax" value="<?php echo $fax; ?>" />
接下来的公司 和公司id 国家 省份 地址1 等等一些列的都用这些办法足以搞定了!我对待地址1的觉得办法就是value='请编辑您的地址' 【有点恶心】
【解决问题-2:订单流程复杂】
简单看了看opencart的订单流程源码,大致的流程是下订单以后,用ajax分步骤处理订单,前5步都没有更新order表,只有在最后的确认订单里更新了order表。如果一点一点修改它的各个步骤,太复杂了,特别是关于地址的问题,一个shoping_address 一个 payment_address ,搞的我乱七八糟的!所有我放弃了这个想法!
所以复杂问题简单化,其实订单类的应用无非就是在订单表里新增数据,订单明细表里新增数据的事情。
我勇敢的选择了重做!思路大致如下!
- 没注册 没登录的一概滚蛋,都踢到注册登录页面,如果登录注册OK后才能下订单!
- 不管什么shopping_address 还是 payment_address 都给我统一,没那么多破地址!
- 没发票没法报销,所以亲们都不爱消费。所以在order表里添加发票台头字段 + 类型字段 【1个人,2单位】
自己做一个checkout的控制器,覆盖原有的checkout控制器/opencart/catalog/controller/checkout/checkout.php
<?php
class ControllerCheckoutCheckout extends Controller {
public function index() {
//判断用户是否登录 没有登录的去注册登录页面
if (!$this->customer->isLogged()) {
//登录完毕后把亲请回来吧
$this->session->data['redirect'] = $this->url->link('checkout/checkout', '', 'SSL');
$this->redirect($this->url->link('account/login', '', 'SSL'));
}
//设置前台文字显示内容
$this->language->load('checkout/mycheckout');
//标题内容
$this->document->setTitle($this->language->get('heading_title'));
//面包渣开始
$this->data['breadcrumbs'] = array();
$this->data['breadcrumbs'][] = array(
'text' => $this->language->get('text_home'),
'href' => $this->url->link('common/home'),
'separator' => false
);
$this->data['breadcrumbs'][] = array(
'text' => $this->language->get('heading_title'),
'href' => $this->url->link('checkout/checkout', '', 'SSL'),
'separator' => $this->language->get('text_separator')
);
//面包渣结束
$this->data['heading_title'] = $this->language->get('heading_title');
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/checkout/mycheckout.tpl')) {
$this->template = $this->config->get('config_template') . '/template/checkout/mycheckout.tpl';
} else {
$this->template = 'default/template/account/mycheckout.tpl';
}
$this->children = array(
'common/content_top',
'common/content_bottom',
'common/footer',
'common/header'
);
$this->response->setOutput($this->render());
}
}
?>
在创建一个 mycheckout.tpl
opencart/catalog/view/theme/default/template/checkout/mycheckout.tpl
在这里面让买家加些地址,配送信息,开-发票信息等!
<?php echo $header; ?>
<div id="content"><?php echo $content_top; ?>
<div class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<?php echo $breadcrumb['separator']; ?><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a>
<?php } ?>
</div>
<form action='http://localhost/cake/index.php?route=checkout/confirmmy' method='post'>
<div>
<p>请填写配送信息:</p>
<p>送货范围:沈阳市二环以内免费送货,二环外加收不等费用,四环外暂不提供送货。送货收费标准:二环外,每公里加收2元。四环外暂不提供送货。</p>
<table align="center" width="100%">
<tbody><tr height="25">
<td align="right" width="8%">配送区域:</td>
<td>辽宁省沈阳市-
<input type='radio' value='1' name='addressarea' checked="checked"> 二环内
<input type='radio' value='2' name='addressarea' checked=""> 二环外-
<select>
<option value="和平区">和平区</option>
<option value="沈河区">沈河区</option>
<option value="大东区">大东区</option>
<option value="皇姑区">皇姑区</option>
<option value="东陵区">东陵区</option>
<option value="铁西区">铁西区</option>
<option value="于洪区">于洪区</option>
</select>
</td>
</tr>
<tr height="25">
<td align="right">详细地址:</td>
<td><input name="address" type="text" id="address" value="" size="50">
(必填)</td>
</tr>
<tr height="25">
<td align="right">收货人姓名:</td>
<td><input name="consignee" type="text" id="consignee" value="" size="20">
(必填) </td>
</tr>
<tr height="25">
<td align="right">联系电话:</td>
<td><input name="mobile" type="text" id="mobile" maxlength="11" value="">(必填)</td>
</tr>
<tr>
<td align="right"></td><td><input type="button" class="bt" name="Submit" value="确认收货人信息">
<input name="address_id" id="addreid" type="hidden" value=""> 信息修改请您点击保存按钮</td>
</tr>
</tbody></table>
<p>配送方式及时间:</p>
<table>
<tr>
<td>请选择配送方式:</td>
<!-- 注意 :此处需要javascript shopping_code 问题 配送方式互动 -->
<input type='hiden' name="shopping_code" value='xxxx' />
<td><select name='shipping_method'><option value='商家为您配送'>商家为您配送</option value='客户自提'><option>客户自提</option></select></td>
</tr>
<tr>
<td>配送或者自提时间:</td>
<td><input type='text' name='sendtime'/></td>
</tr>
</table>
<p>支付方式:</p>
<div>
<p>
<span>
<input type="radio" name="payment_method" value="货到付款" checked="checked" />
<!-- 注意 :此处需要javascript编码解决支付代码问题 与支付方式互动 -->
<input type="hidden" name="payment_code" value="20" />
货到付款
</span>
<span>
<input type="radio" name="payment_method" value="支付宝" />
支付宝
</span>
</p>
</div>
<p>订单附言:</p>
<textarea rows="10" cols="30" name='comment'></textarea>
<input type='submit' value='提交'/>
</from>
</div>
<?php echo $content_bottom; ?></div>
<?php echo $footer; ?>
因为是测试程序,前后台都没有进行校验。用的时候要小心!
这个表单提交到 /opencart/catalog/controller/checkout/confirmmy.php
所以我们还要创建一个confirmmy.php
<?php
class ControllerCheckoutConfirmmy extends Controller {
public function index() {
$redirect = "";
if (!$this->cart->hasShipping()) {
echo "error";
exit();
}
$products = $this->cart->getProducts();
foreach ($products as $product) {
$product_total = 0;
foreach ($products as $product_2) {
if ($product_2['product_id'] == $product['product_id']) {
$product_total += $product_2['quantity'];
}
}
if ($product['minimum'] > $product_total) {
$redirect = $this->url->link('checkout/cart');
break;
}
}
$total_data = array();
$total = 0;
$taxes = $this->cart->getTaxes();
$this->load->model('setting/extension');
/
$sort_order = array();
$results = $this->model_setting_extension->getExtensions('total');
foreach ($results as $key => $value) {
$sort_order[$key] = $this->config->get($value['code'] . '_sort_order');
}
array_multisort($sort_order, SORT_ASC, $results);
foreach ($results as $result) {
if ($this->config->get($result['code'] . '_status')) {
$this->load->model('total/' . $result['code']);
$this->{'model_total_' . $result['code']}->getTotal($total_data, $total, $taxes);
}
}
$sort_order = array();
foreach ($total_data as $key => $value) {
$sort_order[$key] = $value['sort_order'];
}
array_multisort($sort_order, SORT_ASC, $total_data);
$this->language->load('checkout/checkout');
$data = array();
$data['invoice_prefix'] = $this->config->get('config_invoice_prefix');
$data['store_id'] = $this->config->get('config_store_id');
$data['store_name'] = $this->config->get('config_name');
if ($data['store_id']) {
$data['store_url'] = $this->config->get('config_url');
} else {
$data['store_url'] = HTTP_SERVER;
}
if ($this->customer->isLogged()) {
$data['customer_id'] = $this->customer->getId();
$data['customer_group_id'] = $this->customer->getCustomerGroupId();
$data['firstname'] = $_POST['consignee'];
$data['lastname'] = $this->customer->getLastName();
$data['email'] = $this->customer->getEmail();
$data['telephone'] = $_POST['mobile'];
$data['fax'] = $this->customer->getFax();
}
$data['payment_firstname'] = $_POST['consignee'];
//$data['payment_lastname'] = $payment_address['lastname'];
$data['payment_company'] = "";
$data['payment_company_id'] = "";
$data['payment_tax_id'] = "";
$data['payment_address_1'] = $_POST['address'];
$data['payment_address_2'] = "";
$data['payment_city'] = "沈阳";
$data['payment_postcode'] = "110032";
$data['payment_zone'] = "辽宁";
$data['payment_zone_id'] = "703";
$data['payment_country'] = "中国";
$data['payment_country_id'] = "44";
$data['payment_address_format'] = "";
$data['payment_method'] = $_POST['payment_method'];
$data['payment_code'] = $_POST['payment_code'];
$data['shipping_firstname'] = $_POST['consignee'];
$data['shipping_company'] = "";
$data['shipping_address_1'] = $_POST['address'];
$data['shipping_address_2'] = "";
$data['shipping_city'] = "沈阳";
$data['shipping_postcode']= "110032";
$data['shipping_zone'] = "辽宁";
$data['shipping_zone_id'] = "703";
$data['shipping_country'] = "中国";
$data['shipping_country_id'] = "44";
$data['shipping_address_format'] = "";
$data['shipping_method'] = $_POST['payment_method'];
$data['shipping_code'] = $_POST['payment_code'];
$product_data = array();
foreach ($this->cart->getProducts() as $product) {
$option_data = array();
foreach ($product['option'] as $option) {
if ($option['type'] != 'file') {
$value = $option['option_value'];
} else {
$value = $this->encryption->decrypt($option['option_value']);
}
$option_data[] = array(
'product_option_id' => $option['product_option_id'],
'product_option_value_id' => $option['product_option_value_id'],
'option_id' => $option['option_id'],
'option_value_id' => $option['option_value_id'],
'name' => $option['name'],
'value' => $value,
'type' => $option['type']
);
}
$product_data[] = array(
'product_id' => $product['product_id'],
'name' => $product['name'],
'model' => $product['model'],
'option' => $option_data,
'download' => $product['download'],
'quantity' => $product['quantity'],
'subtract' => $product['subtract'],
'price' => $product['price'],
'total' => $product['total'],
'tax' => $this->tax->getTax($product['price'], $product['tax_class_id']),
'reward' => $product['reward']
);
}
// Gift Voucher
$voucher_data = array();
if (!empty($this->session->data['vouchers'])) {
foreach ($this->session->data['vouchers'] as $voucher) {
$voucher_data[] = array(
'description' => $voucher['description'],
'code' => substr(md5(mt_rand()), 0, 10),
'to_name' => $voucher['to_name'],
'to_email' => $voucher['to_email'],
'from_name' => $voucher['from_name'],
'from_email' => $voucher['from_email'],
'voucher_theme_id' => $voucher['voucher_theme_id'],
'message' => $voucher['message'],
'amount' => $voucher['amount']
);
}
}
$data['products'] = $product_data;
$data['vouchers'] = $voucher_data;
$data['totals'] = $total_data;
$data['comment'] = $_POST['comment'];
$data['total'] = $total;
//
if (isset($this->request->cookie['tracking'])) {
$this->load->model('affiliate/affiliate');
$affiliate_info = $this->model_affiliate_affiliate->getAffiliateByCode($this->request->cookie['tracking']);
$subtotal = $this->cart->getSubTotal();
if ($affiliate_info) {
$data['affiliate_id'] = $affiliate_info['affiliate_id'];
$data['commission'] = ($subtotal / 100) * $affiliate_info['commission'];
} else {
$data['affiliate_id'] = 0;
$data['commission'] = 0;
}
} else {
$data['affiliate_id'] = 0;
$data['commission'] = 0;
}
$data['language_id'] = $this->config->get('config_language_id');
$data['currency_id'] = $this->currency->getId();
$data['currency_code'] = $this->currency->getCode();
$data['currency_value'] = $this->currency->getValue($this->currency->getCode());
$data['ip'] = $this->request->server['REMOTE_ADDR'];
if (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) {
$data['forwarded_ip'] = $this->request->server['HTTP_X_FORWARDED_FOR'];
} elseif(!empty($this->request->server['HTTP_CLIENT_IP'])) {
$data['forwarded_ip'] = $this->request->server['HTTP_CLIENT_IP'];
} else {
$data['forwarded_ip'] = '';
}
if (isset($this->request->server['HTTP_USER_AGENT'])) {
$data['user_agent'] = $this->request->server['HTTP_USER_AGENT'];
} else {
$data['user_agent'] = '';
}
if (isset($this->request->server['HTTP_ACCEPT_LANGUAGE'])) {
$data['accept_language'] = $this->request->server['HTTP_ACCEPT_LANGUAGE'];
} else {
$data['accept_language'] = '';
}
$this->load->model('checkout/order');
$this->session->data['order_id'] = $this->model_checkout_order->addOrder($data);
$this->data['column_name'] = $this->language->get('column_name');
$this->data['column_model'] = $this->language->get('column_model');
$this->data['column_quantity'] = $this->language->get('column_quantity');
$this->data['column_price'] = $this->language->get('column_price');
$this->data['column_total'] = $this->language->get('column_total');
$this->data['products'] = array();
foreach ($this->cart->getProducts() as $product) {
$option_data = array();
foreach ($product['option'] as $option) {
if ($option['type'] != 'file') {
$value = $option['option_value'];
} else {
$filename = $this->encryption->decrypt($option['option_value']);
$value = utf8_substr($filename, 0, utf8_strrpos($filename, '.'));
}
$option_data[] = array(
'name' => $option['name'],
'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value)
);
}
$this->data['products'][] = array(
'product_id' => $product['product_id'],
'name' => $product['name'],
'model' => $product['model'],
'option' => $option_data,
'quantity' => $product['quantity'],
'subtract' => $product['subtract'],
'price' => $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax'))),
'total' => $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax')) * $product['quantity']),
'href' => $this->url->link('product/product', 'product_id=' . $product['product_id'])
);
}
// Gift Voucher
$this->data['vouchers'] = array();
if (!empty($this->session->data['vouchers'])) {
foreach ($this->session->data['vouchers'] as $voucher) {
$this->data['vouchers'][] = array(
'description' => $voucher['description'],
'amount' => $this->currency->format($voucher['amount'])
);
}
}
$this->data['totals'] = $total_data;
$this->data['payment'] = $_POST['payment_method'];
$redirect = $this->url->link('checkout/success', '', 'SSL');
$this->data['redirect'] = $redirect;
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/checkout/confirm.tpl')) {
$this->template = $this->config->get('config_template') . '/template/checkout/confirm.tpl';
} else {
$this->template = 'default/template/checkout/confirm.tpl';
}
$this->response->setOutput($this->render());
}
}
?>
这样基本上大功告成了!
要发票吗? 如果要发票的话需要在order表中加字段,然后修改/open/catalog/model/checkout/order.php中的addOrder方法 把发票字段赋值。此处省略一万字!
其实这就是一个简化的思路,并不是简化的成品,有很多地方存在不足,和漏洞,希望大家能够相互沟通来完善中国特色的opencart!
我期待和大家交流Opencart 二次开发,也期待做APP的朋友与我交流,现在正在改opencart 与APP交互【 iphone and android 】