月度归档:2013年07月

Zen-cart Geo-zone扩展

Zen-cart扩展Geo-Zone管理

可以参考Zen-cart中的地区与税率

这里主要扩展了geo_zones这个表进行扩展,后台文件对应admin/geo_zones.php

//加入如下代码防止错误
///////////////////////
$cnt = $db->metaColumns(TABLE_GEO_ZONES);
if(!isset($cnt['COST'])){
	$db->Execute("ALTER TABLE ".TABLE_GEO_ZONES." ADD cost VARCHAR( 256 ) NULL DEFAULT ''");
}
if(!isset($cnt['GEO_ZONE_TYPE_ID'])){
	$db->Execute("ALTER TABLE ".TABLE_GEO_ZONES." ADD geo_zone_type_id int(11) NOT NULL DEFAULT '0'");
}
///////////////////////

cost字段主要用来保存这个区的费率,geo_zone_type_id用来对geo_zone进行分类,标识这个区是哪种类型,比如DHL或Fedex类型的分区:
Zen-cart新表geo_zones_type

其它改动就是调整查询插入更新时的相关的SQL,不过在新添加或编辑Geo_Zone时,需要下拉出Geo_Zone_Type:

zen_draw_pull_down_menu('geo_zone_type_id', zen_get_zone_types("请选择Geo Zone Type")

//zen_get_zone_types()函数
function zen_get_zone_types($default = '') {
    global $db;

	$zone_class_array = array();
    if ($default) {
      	$zone_class_array[] = array('id' => '',
                                 'text' => $default);
    }

    $zone_class = $db->Execute("select geo_zone_type_id, geo_zone_type_name
                                from " . TABLE_GEO_ZONES_TYPE . "
                                order by geo_zone_type_name");

    while (!$zone_class->EOF) {
      	$zone_class_array[] = array('id' => $zone_class->fields['geo_zone_type_id'],
                                  'text' => $zone_class->fields['geo_zone_type_name']);
      	$zone_class->MoveNext();
    }
	return $zone_class_array;
}

这个就可以在后台管理Geo_Zone对应的费率(cost)了。每个Geo_Zone里面包含了一个或多个国家,它们对应一个费率,再由Geo_Zone_Type知道是哪种Geo_Zone,然后可以安装规则计算运费。这个扩展意义就在这里了。

永久链接:http://blog.ifeeline.com/946.html

Zen-cart 扩展国家表管理

Zen-cart中国家表的管理比较粗糙,特别是在要对应国家下拉列表进行调整时,比如把常用的国家调整到最前面,那么就需要扩展一下国家表字段了。

Zen-cart国家表管理扩展

涉及到国家表管理的是admin/countries.php文件,需要对这个文件做一些改动:

///////////////////////
$cnt = $db->metaColumns(TABLE_COUNTRIES);
if(!isset($cnt[strtoupper('countries_name_cn')])){	
	$db->Execute("ALTER TABLE ".TABLE_COUNTRIES." ADD countries_name_cn VARCHAR( 64 ) NULL DEFAULT ''");
}
if(!isset($cnt[strtoupper('order_by')])){	
	$db->Execute("ALTER TABLE ".TABLE_COUNTRIES." ADD order_by int(11) NOT NULL DEFAULT '0'");
}
///////////////////////

然后就是对插入编辑时的SQL进行修改,当然接下来还有修改表单(这里忽略)。

Zen-cart国家表字段编辑

这样可以添加中文名称和排序码,排序码添加了之后还要修改两个获取国家下拉列表的函数(前台后台分别对应一个):

#includes/functions/functions_lookups.php
  function zen_get_countries($countries_id = '', $with_iso_codes = false) {
    global $db;

    $countries_array = array();
    if (zen_not_null($countries_id)) {
    } else {
	  ///////////////////////
	  $cnt = $db->metaColumns(TABLE_COUNTRIES);
	  if(!isset($cnt[strtoupper('order_by')])){	
		$db->Execute("ALTER TABLE ".TABLE_COUNTRIES." ADD order_by int(11) NOT NULL DEFAULT '0'");
	  }
	  ///////////////////////
      $countries = "select countries_id, countries_name
                    from " . TABLE_COUNTRIES . "
                    order by order_by, countries_name";

      $countries_values = $db->Execute($countries);

      while (!$countries_values->EOF) {
        $countries_array[] = array('countries_id' => $countries_values->fields['countries_id'],
                                   'countries_name' => $countries_values->fields['countries_name']);

        $countries_values->MoveNext();
      }
    }

    return $countries_array;
  }

#admin/includes/functions/general.php
  function zen_get_countries($default = '') {
    global $db;
    $countries_array = array();
    if ($default) {
      $countries_array[] = array('id' => '',
                                 'text' => $default);
    }
	
	///////////////////////
	$cnt = $db->metaColumns(TABLE_COUNTRIES);
	if(!isset($cnt[strtoupper('countries_name_cn')])){	
		$db->Execute("ALTER TABLE ".TABLE_COUNTRIES." ADD countries_name_cn VARCHAR( 64 ) NULL DEFAULT ''");
	}
	if(!isset($cnt[strtoupper('order_by')])){	
		$db->Execute("ALTER TABLE ".TABLE_COUNTRIES." ADD order_by int(11) NOT NULL DEFAULT '0'");
	}
	///////////////////////

    $countries = $db->Execute("select countries_id, countries_name,countries_name_cn
                               from " . TABLE_COUNTRIES . "
                               order by order_by, countries_name");

    while (!$countries->EOF) {
      $countries_array[] = array('id' => $countries->fields['countries_id'],
                                 'text' => $countries->fields['countries_name']." - ".$countries->fields['countries_name_cn']);
      $countries->MoveNext();
    }

    return $countries_array;
  }

Zen-cart国家调整排序

Zen-cart管家管理后台界面

函数中加入了判断对应字段是否存在的逻辑,防止出错。

永久链接:http://blog.ifeeline.com/940.html

自动采集同步备忘录

自动采集同步

nmnbx_get_cats.php					自动抓取目录,每次抓一个入口,受频率参数控制
nmnbx_get_cats.php?f=force				自动抓取目录,不受频率参数控制,针对全部入口
nmnbx_get_cats.php?f=force&id=**		        自动抓取目录,不受频率参数控制,针对具体入口,有id指定


nmnbx_scan_cats.php					扫描全部目录
nmnbx_scan_cats.php?id=**				扫描指定目录,有id指定

nmnbx_get_prods.php					根据scan_cats.php扫描的结果抓取产品

nmnbx_syncs.php						把抓取到的产品同步到远程,远程用post.php接收数据

nmnbx_post.php						处理客户端发送过来的数据并写入数据库

nmnbx_get_mimgs.php					采集产品主图(750PX)

nmnbx_get_dimgs.php					采集产品描述图(700PX)
nmnbx_dimgs_is_exists.php				描述图片是否存在

nmnbx_cut_dimg_to_mimg.php			        根据描述图裁切产品主图(此程序可去掉,由nmnbx_get_mimgs.php代替,不过由于某些原因,nmnbx_get_mimgs.php获取的图片尺寸小,可以考虑使用从描述图裁切大图)

nmnbx_cut_dimg_to_dimg.php			        根据描述图裁切描述图(去掉每张描述图前的主图)

后台程序:
产品属性对应语言管理nmnbxlan_manage.php,扫描所有产品属性,获取各种情况,然后对应相关翻译,保存在nmnbx_translates
语言翻译

产品名称对应语言管理prodslan_manage.php
产品名称翻译

目前存在问题:
产品的详细信息变动没有程序进行处理。

永久连接: http://blog.ifeeline.com/933.html

运单号自动跟踪管理 – 流程备忘

数据表:
数据表 tracks

hash		运单号的哈希码,由于是抓第三方的数据,这个哈希码是由第三方提供的
delivery_date	发货日期
track		跟踪号
shipping_piece	件数
shipping_weight	重量
shipping_method	运输方式
shipping_to	目的地
shipping_cost	运费
delivery_status	运输状态,0表示无法查询 1表示正在运输 2等待提取 3已经签收 4客户确认
delivery_days	运输花费的天数
update_date	用来控制当查询失败后当天不在重复查询
last_update_time最后更新的时间
return_back	是否为退件
total_track	自动跟踪的天数
stop_track	是否停止跟踪(对应超过一定天数的运单,如果没有签收就停止跟踪)
del		是否被删除
note		运单备注
data		查询时获取的数据(保存最新的数据)

我们需要安装一定格式把运单导入:
运单上传文件格式

格式文件下载:上传文件格式文件

文件上传编写了一个接口,文件名为import_track.php,可以安装这个格式把输入导入。

运单管理的文件名为tracks_manage.php,实现灵活查询过滤排序:
upload_format

运单跟踪管理

用户接口就备忘到此。

以下是实现自动跟踪更新运单信息的流程:
自动更新流程

一共涉及4个文件,post.php专门用来实现接收数据并把数据导入到数据的逻辑,auto_client.php通过浏览器ajax的方法远程抓取到数据后提交给post.php,一般只需要在浏览器打开它并且设置它隔一段时间自动刷新就可以自动更新运单信息了,auto_server.php和auto_client.php差不多一样,不过这个是服务器端通过php远程抓取数据后提交给post.php,这个可以在服务器上设置crontab任务自动执行(不过PHP远程抓取数据很耗资源,不太适合干这个,实际上采用客户端工具的ajax来进行,效果更好),另外一个就是force_track.php,由于自动跟踪设置了一定时间间隔,并且当天查询失败的运单,当天不会再次查询(要等到第二天才会被再次查询,主要为了防止可能引发循环获取失败资源导致远程服务器封杀),所以用它可以强制刷新运单的跟踪信息。

总体上,再也不用自己手动跟踪了,此为备忘。

永久链接:http://blog.ifeeline.com/921.html

PHP函数参考 – 其它基本扩展 – URLs

PHP对URL的处理函数列表:

    base64_decode    — 对使用 MIME base64 编码的数据进行解码
    base64_encode    — 使用 MIME base64 对数据进行编码
    get_headers      — 取得服务器响应一个 HTTP 请求所发送的所有标头
    get_meta_tags    — 从一个文件中提取所有的 meta 标签 content 属性,返回一个数组
    http_build_query — 生成 URL-encode 之后的请求字符串
    parse_url        — 解析 URL,返回其组成部分
    rawurldecode     — 对已编码的 URL 字符串进行解码
    rawurlencode     — 按照 RFC 1738 对 URL 进行编码
    urldecode        — 解码已编码的 URL 字符串
    urlencode        — 编码 URL 字符串

这些函数还是核心的一部分,是常用的并且需要记忆的函数。

1 base64_decode 和 base64_encode这对函数实现base64算法。

2 get_headers()方法就是获取HTTP响应的头信息,例子:

print_r(get_headers("http://blog.ifeeline.com"));
//输出
Array
(
    [0] => HTTP/1.1 200 OK
    [1] => Server: nginx
    [2] => Date: Sun, 30 Jun 2013 15:26:47 GMT
    [3] => Content-Type: text/html; charset=UTF-8
    [4] => Connection: close
    [5] => Vary: Accept-Encoding
    [6] => X-Pingback: http://blog.ifeeline.com/xmlrpc.php
)

2 get_meta_tags()函数提取meta标签的content 属性值。

3 http_bulid_query()函数生成 URL-encode 之后的请求字符串,具体可参考http://www.php.net/manual/zh/function.http-build-query.php

string http_build_query ( mixed $query_data [, string $numeric_prefix [, string $arg_separator [, int $enc_type = PHP_QUERY_RFC1738 ]]] )

这个函数需要注意,$query_data可以是数组或对象,$numeric_prefix作为变量前缀,它主要为了辅助生成合法的下标,$arg_separator就是查询字符串中分隔符,没有指定就是配置文件中的arg_separator.output,$enc_type表示编码类型,默认是PHP_QUERY_RFC1738,它跟表单提交数据时使用的编码一致(空格变成加号,如果是PHP_QUERY_RFC3986,空格会被编码成%20),这个是PHP5.4加入的。
例子:

$data = array('foo'=>'bar',
              'baz'=>'boom',
              'cow'=>'milk',
              'php'=>'hypertext processor');

echo http_build_query($data) . "\n";
echo http_build_query($data, '', '&'). "\n";
echo http_build_query($data, '', '&',PHP_QUERY_RFC3986). "\n";//PHP5.4+可用
//输出
foo=bar&baz=boom&cow=milk&php=hypertext+processor
foo=bar&baz=boom&cow=milk&php=hypertext+processor
foo=bar&baz=boom&cow=milk&php=hypertext%20processor

注意空格变成了+号或被编码成了%20。

4 parse_url()解析 URL,返回关联数组

5 rawurlencode() rawurlencode()和urldecode() urlencode()
这两对函数基本一致,只是在对待空格问题上有差别,rawurlencode()把空格变成加号(%20),urldecode()把空格变成加号。需要注意的是,urldecode()把空格变成加号与 WWW 表单 POST 数据的编码方式是一样的,同时与 application/x-www-form-urlencoded 的媒体类型编码方式一样。


注释:

实际上,PHP5.3之前,rawurlencode和urldecode都采用RFC 1738标准来编码,只是urlencode在对待空格问题上把它换成加号以兼容POST表单的数据编码,PHP5.3以后,rawurlencode完全遵循RFC 3986编码方案,空格还是变成%20(raw表示未加工的)。注意到http_bulid_query()在生成查询字符串时,还是跟urlencode函数一致将空格换成了+号,就没有什么奇怪的了,因为它需要兼容POST表单的编码方式。

当以POST方式提交表单时,HTTP头的Content-type默认是application/x-www-form-urlencoded,表示表单的数据是经过urlencode的,这样Web服务器在获取到数据后就知道需要先urldecode了,如果采用HTML表单提交数据到服务器,这个过程是自动完成的,如果是采用socket或curl方式POST数据,那么这些数据就需要自己进行urlencode,否则如果传输的数据带有加号(没有转换),Web服务器收到后把加号变成空格,显然,这个不是你期望的结果。

另外,在jQuery中的ajax函数,使用data传递参数时,默认也是采用了urlencode的,兼容HTML表单的POST提交。

原创文章,转载务必保留出处。
永久连接: http://blog.ifeeline.com/918.html