月度归档:2012年12月

Zen-cart 插件 Admin New Customer 安装使用与改进

Zen-cart 插件 Admin New Customer下载地址:http://www.zen-cart.com/downloads.php?do=file&id=1501
我下载的是admin_new_customer_1.1版本,它只针对Zer-cart 1.5.0 +版本。
此插件有修改zen-cart原文件,使用Winmerge比对可以知道:

1 admin/customers.php文件的1179行后添加(增加一个连接):
<?php
    if(empty($action)) { ?>
              <tr>
                <td align="right" colspan="10" class="smallText"><?php echo '<a href="' . zen_href_link(FILENAME_NEW_CUSTOMER) . '">' . zen_image_button('button_insert.gif', IMAGE_INSERT) . '</a>'; ?></td>
              </tr><?php
    } ?>
2 admin/includes/functions/html_output.php
172行后添加:
      $output_string .= '    hideStateField(' . $form . ');' . "\n" ;
175行后添加:
                      '    showStateField(' . $form . ');' . "\n" .
179行后添加:
  ////
  // javascript to dynamically update the states/provinces list when the country is changed
  // TABLES: zones
  function zen_js_billing_zone_list($country, $form, $field) {
  	global $db;
  	$countries = $db->Execute("select distinct zone_country_id
  			from " . TABLE_ZONES . "
  			order by zone_country_id");

  	$num_country = 1;
  	$output_string = '';
  	while (!$countries->EOF) {
  		if ($num_country == 1) {
  			$output_string .= '  if (' . $country . ' == "' . $countries->fields['zone_country_id'] . '") {' . "\n";
  		} else {
  			$output_string .= '  } else if (' . $country . ' == "' . $countries->fields['zone_country_id'] . '") {' . "\n";
  		}

  		$states = $db->Execute("select zone_name, zone_id
  				from " . TABLE_ZONES . "
  				where zone_country_id = '" . $countries->fields['zone_country_id'] . "'
  				order by zone_name");


  		$num_state = 1;
  		while (!$states->EOF) {
  			if ($num_state == '1') $output_string .= '    ' . $form . '.' . $field . '.options[0] = new Option("' . PLEASE_SELECT . '", "");' . "\n";
  			$output_string .= '    ' . $form . '.' . $field . '.options[' . $num_state . '] = new Option("' . $states->fields['zone_name'] . '", "' . $states->fields['zone_id'] . '");' . "\n";
  			$num_state++;
  			$states->MoveNext();
  		}
  		$num_country++;
  		$countries->MoveNext();
  		$output_string .= '    hideBillingStateField(' . $form . ');' . "\n" ;
  	}
  	$output_string .= '  } else {' . "\n" .
  			'    ' . $form . '.' . $field . '.options[0] = new Option("' . TYPE_BELOW . '", "");' . "\n" .
  			'    showBillingStateField(' . $form . ');' . "\n" .
  			'  }' . "\n";

  	return $output_string;
  }

3 admin/includes/languages/english.php 文件中修改了一些常量定义值。

4 includes/functions/password_funcs.php文件的118行[$entropy = sha1_file('/includes/configure.php');]替换成(实际是换成绝对路径):
$entropy = sha1_file(DIR_FS_CATALOG . DIR_WS_INCLUDES . 'configure.php');

一般只要直接覆盖即可,除非对这些文件有修改。

看第四点,这里修正了Zen-cart1.5.1的一个Bug,原版居然直接使用’/includes/configure.php’子串。
覆盖安装,进入后台->Customers->Customers,点击Insert,显示警告:

WARNING: An Error occurred, please refresh the page and try again.

//查看日志发现
[19-Dec-2012 05:39:18 UTC] PHP Fatal error:  1366:Incorrect integer value: '' for column 'entry_zone_id' at row 1 :: insert into address_book (customers_id, entry_company, entry_firstname, entry_lastname, entry_street_address, entry_suburb, entry_postcode, entry_city, entry_state, entry_zone_id, entry_country_id) values ('1', '', 'jerry', 'saa', 'guangzhou, guangdong', '', '6666', 'guangzhou', '', '', '223') in D:\www\web\z151.com\public_html\includes\classes\db\mysql\query_factory.php on line 120

日志提示说不正确的整数值,应该是Mysql配置成了严格模式,修改为:

#sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

重启Mysql后,警告消除。

在zent-cart1.5.0以前的版本,在处理国家的省份时存在Bug,大体是如果国家没有设置省份,那么应该让客户自己输入,但是如果自己输入就永远无法通过验证,这个Bug在zent-cart1.5.x中已经被修复,可惜这个插件的代码还是使用存在Bug的那个代码段,所以需要做一些修改才行:
admin_new_customer_state
对应代码修改为:

$entry_state_has_zones = ($check->fields['total'] > 0);
if ($entry_state_has_zones == true) {
    //......
}else{
    if (strlen($cInfo->entry_state) < ENTRY_STATE_MIN_LENGTH) {
	$messageStack->add(ENTRY_STATE_ERROR);
	break;
    }
}
//在处理Bill地址时也一样逻辑

具体修改需要比对admin/new_customer.php文件,修正程序包下载:admin_new_customer_1.1_fix_by_blog.ifeeline.com

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

Zen-cart 使用反向代理后后台whos_online功能的修正

如果Zen-cart程序放置在反向代理服务器之后,后台whos_online功能显示的都是前端方向代理服务器的IP,那么这样就无法分辨有多少个人在线了。目前最常用的反向代理当数Nginx了,在配置中一般使用如下指令:

proxy_set_header X-Forwarded-For $remote_addr;

它把当前的真实访问的IP通过X-Forwarded-For传递给后端服务器,这样后端就可以记录下真实的IP。

Zen-cart中后端的whos_online功能获取IP是在includes/functions/whos_online.php文件中实现的,所以需要修改一下这个文件,主要判断如果存在X-Forwarded-For这个值,就使用它来作为真实IP:

//新增加的函数,用来判断是否是合法的IP
function is_ip($str) {
	$ip = explode(".", $str);
	if (count($ip) < 4 || count($ip) > 4) return 0;
	foreach($ip as $ip_addr) {
		if ( !is_numeric($ip_addr) ) return 0;
		if ( $ip_addr < 0 || $ip_addr > 255 ) return 0;
	}
    return (preg_match("/^([0-9]{1,3}\.){3}[0-9]{1,3}$/is", $str));
}
//修改function zen_update_whos_online()函数,把“$wo_ip_address = (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'Unknown');”使用如下代码替代:
//////////////////////////
$r = '';
$x = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
for ($i=0;$i<count($x);$i++) {
	$x[$i]=trim($x[$i]);
	if(is_ip($x[$i])) {
		$r=$x[$i];
		break;
	}
}
if($r != ''){
	$wo_ip_address = $r;
}else{
	$wo_ip_address = (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'Unknown');
}
//////////////////////////

这里只要修改其获取正确IP地址即可,接下来统计多少客户在线、重复IP和非重复客户是基于IP和会话ID的。至此,后台whos_online功能修改完毕。

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

Zen-cart 插件 “Fast and Easy AJAX Checkout for Zen Cart” bug??

Fast and Easy AJAX Checkout for Zen Cart购买地址:
https://www.numinix.com/zen-cart-modules/checkout/fast-and-easy-ajax-checkout-for-zen-cart-dl-797
现在是150刀,以前是75刀,价格翻了一翻,真是贱的很。不过有一个对应的免费的版本叫:Fast and Easy Checkout for Zen Cart(没有Ajax),这个版本也很贱,总让你不舒服,然后让你想去花钱买那个付费版本,花钱买了付费版本还不算,这个付费版本可能还有一些预留的Bug,然后让你购买它们提供的安装服务(35刀),这个鬼佬贱到家了。

我下载了付费的版本2.24.1的插件,安装完毕后在日志中就产生如下警告:

[10-Dec-2012 02:05:08 UTC] PHP Warning:  Missing argument 1 for ot_coupon::get_order_total(), called in D:\www\web\z151.com\public_html\includes\modules\order_total\ot_coupon.php on line 510 and defined in D:\www\web\z151.com\public_html\includes\modules\order_total\ot_coupon.php on line 595

打开ot_coupon.php检查510行 和 595行:

...
$orderTotal = $this->get_order_total();
…
function get_order_total($couponCode){

发现,get_order_total函数是要带参数的,而510行调用的时候并没有带参数,所以导致警告。ot_coupon.php这个文件是内核文件,但是它被插件提供的文件覆盖了,查看了下原来的文件发现get_order_total函数并没有被修改,所以调用get_order_total不带参数应该是覆盖的文件导致的警告,修改为:

$this->get_order_total((int)$_SESSION['cc_id']);

当把代码放到生成环境时,出现如下错误:
[10-Dec-2012 02:46:17 UTC] PHP Parse error: syntax error, unexpected ‘}’ in /web/www.ifeeline.com/public_html/includes/templates/cot/templates/quick_checkout/tpl_modules_qc_shipping.php on line 119
检查tpl_modules_qc_shipping.php文件并没有发现大括号不对应问题,而且在本地可以正常运行,到了生产服务器就出现这样的错误,后发现如下代码(文件87行附近):

<?          
for ($j = 0; $j < $quotes[$i]['email_no']; $j++) {
?>

PHP的界定符没有使用标准做法(少写php),而其它的都是标准写法,这才知道这是短标签问题,本地PHP环境配置是:

short_open_tag = On

而服务器配置是 Off。

把代码的短标签修改为标准写法,代码运行正常。

这里基本可以肯定的说,这个短标签问题是人为预留,因为其它都是标准写法,唯独有一个是短标签,对于关闭了短标签配置的服务器,这个错误很难被发现。最后你可能要去购买它的安装服务了,35刀安装一次,跟抢一样。

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

Zen-cart 插件 Image Handler4 for v1.5.x 安装使用

Zen-cart 插件 Image Handler4 for v1.5.x 下载链接:
http://www.zen-cart.com/downloads.php?do=file&id=1380

插件主要涉及如下文件修改:

/YOUR_ADMIN/includes/modules/category_product_listing_IH4.php -> /YOUR_ADMIN/includes/modules/category_product_listing.php
/includes/modules/pages/popup_image/header_php_IH4.php -> /includes/modules/pages/popup_image/header_php.php
/includes/modules/pages/popup_image_additional/header_php_IH4.php -> /includes/modules/pages/popup_image_additional/header_php.php
/includes/modules/IH_INSTALL/additional_images.php -> /includes/modules/YOUR_TEMPLATE/additional_images.php
/includes/modules/IH_INSTALL/main_product_image.php -> /includes/modules/YOUR_TEMPLATE/main_product_image.php
/includes/templates/IH_INSTALL/popup_image_additional/tpl_main_page.php -> /includes/templates/YOUR_TEMPLATE/popup_image_additional/tpl_main_page.php

/YOUR_ADMIN/includes/modules/category_product_listing.php
/includes/modules/pages/popup_image/header_php.php
/includes/modules/pages/popup_image_additional/header_php.php
此插件实际修改了此三个核心文件,另外三个其中两个是模板覆盖,一个是模板文件。

参考:

//安装时,覆盖的核心文件
$core_files = array(
	array(DIR_FS_ADMIN.'includes/modules/category_product_listing.php',DIR_FS_ADMIN.'includes/modules/category_product_listing_IH4.php'),
       	array(DIR_FS_CATALOG.'includes/modules/pages/popup_image/header_php.php',DIR_FS_CATALOG.'includes/modules/pages/popup_image/header_php_IH4.php'),
      	array(DIR_FS_CATALOG.'includes/modules/pages/popup_image_additional/header_php.php',DIR_FS_CATALOG.'includes/modules/pages/popup_image_additional/header_php_IH4.php'),
);

//卸载时,还原文件
$rollback_files = array(
    	array(DIR_FS_ADMIN.'includes/modules/category_product_listing.php',DIR_FS_ADMIN.'includes/modules/category_product_listing.DEFAULT.php.bak'),
      	array(DIR_FS_CATALOG.'includes/modules/pages/popup_image/header_php.php',DIR_FS_CATALOG.'includes/modules/pages/popup_image/header_php.DEFAULT.php.bak'),
     	array(DIR_FS_CATALOG.'includes/modules/pages/popup_image_additional/header_php.php',DIR_FS_CATALOG.'includes/modules/pages/popup_image_additional/header_php.DEFAULT.php.bak'),
);

IH4这个版本是针对Zen-cart1.5.0以上的版本的,在安装和卸载方面做了一些自动化的处理。基本上,把文件拷贝进入对应目录,然后打开后台就会自动安装,对于涉及到的文件覆盖,比如category_product_listing_IH4.php到category_product_listing.php,首先是把原来的category_product_listing.php命名为类似category_product_listing.phpIH_1354760956.bak,然后把category_product_listing_IH4.php改为category_product_listing.php,对于卸载,把当前的category_product_listing.php重命名为类似category_product_listing.phpIH_1354760956.bak,然后把category_product_listing.DEFAULT.php.bak拷贝为category_product_listing.php,之后再把category_product_listing.DEFAULT.php.bak删除。

理顺一下:
插件拷贝进入的文件有category_product_listing_IH4.php 和 category_product_listing.DEFAULT.php.bak,安装时category_product_listing_IH4.php被重命名了,如果卸载了那么category_product_listing.DEFAULT.php.bak被删除了,可见category_product_listing_IH4.php是被修改过的文件,category_product_listing.DEFAULT.php.bak是原来的系统没有修改过的文件,安装时使用修改过的文件,卸载时把没有修改过的对应回去,安装 和 卸载过程都产生了category_product_listing.phpIH_xxxxxx.bak这样的备份文件,实在是有点不干净。

修改一下:
修改对应文件,让其直接对应到最终文件,包含覆盖文件,让其拷贝覆盖,然后打开后台就完成安装。自动安装了之后如果卸载,修改其只删除配置项(不删除文件,如果要对应回来只要手动修改3个被覆盖的核心文件即可,这样就不存在很多垃圾文件了)。

附上修改的版本(仅供参考):
Image_HandlerV4修改版

IH4基本的工作原理:
在includes/functions/html_output.php中的zen_image()函数:

  function zen_image($src, $alt = '', $width = '', $height = '', $parameters = '') {
    global $template_dir, $zco_notifier;
    // ....
    if (function_exists('handle_image')) {
      $newimg = handle_image($src, $alt, $width, $height, $parameters);
      list($src, $alt, $width, $height, $parameters) = $newimg;
      $zco_notifier->notify('NOTIFY_HANDLE_IMAGE', array($newimg));
    }
    //.....

如果存在handle_image函数,则使用这个函数对图片进行处理。IH4正是使用这个预留“钩子”实现缓存图片的功能。handle_image函数在includes/functions/extra_functions/functions_bmz_image_handler.php中定义,这个文件中读入配置参数,然后调用includes/classes/bmz_image_handler.php中定义的ih_image类实例来处理图片缓存。

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

Zen-cart插件 css_js_loader 人为预留错误?

Zen-cart插件 css_js_loader 下载页:
https://www.numinix.com/zen-cart-modules/other-modules/css-js-loader

这个插件是Numinix提供的免费插件,用来压缩CSS和JS,针对页面控制CSS或JS脚本的加载,是一个实用插件,不过2.0.0和2.1.0版本或以后版本都存在一个人为的预留错误。

按照说明安装完毕之后,后台启用CSS和JS压缩:

然后访问前台,发现样式没有起作用,查看源码:

<link rel="stylesheet" type="text/css" href="min/?f=/includes/templates/cmm/css/stylesheet.css&1354635372" />

就在源码中点击这个链接,在chrome中得到:

意思就是链接不存在,查看一下PHP产生的日志:

[04-Dec-2012 15:36:12 UTC] PHP Warning:  fopen(D:/www/web/in.data/min/cache/minify_stylesheet,stylesheet_css_buttons.css_2f5c85de52b3d1be4c806900d7346742) [function.fopen]: failed to open stream: No such file or directory in D:\www\web\in.data\min\lib\Minify\Cache\File.php on line 100
[04-Dec-2012 15:36:12 UTC] PHP Warning:  flock() expects parameter 1 to be resource, boolean given in D:\www\web\in.data\min\lib\Minify\Cache\File.php on line 101
[04-Dec-2012 15:36:12 UTC] PHP Warning:  stream_get_contents() expects parameter 1 to be resource, boolean given in D:\www\web\in.data\min\lib\Minify\Cache\File.php on line 102
[04-Dec-2012 15:36:12 UTC] PHP Warning:  flock() expects parameter 1 to be resource, boolean given in D:\www\web\in.data\min\lib\Minify\Cache\File.php on line 103
[04-Dec-2012 15:36:12 UTC] PHP Warning:  fclose() expects parameter 1 to be resource, boolean given in D:\www\web\in.data\min\lib\Minify\Cache\File.php on line 104

第一条日志就说明文件不存在,无法打开,产生了警告错误日志。

那么去min目录下查看文件,发现根本没有cache目录,所以压缩文件当然不存在了。建立cache目录,之后,缓存生成,样式正常了。

如何认定这是一个人为的预留错误呢? CSS/JS Loader是一个由Numinix免费提供的Zen-cart插件,虽然是免费的,但是如果要请它安装就要收费35美金,这个插件安装只是拷贝文件如此而已,Numinix在2.0.0以后删除了cache目录,人为添加了一个错误,如果没有错误当然不会有人请它安装了,它的目的是不言而喻,都说天下没有免费的午餐,此一例。恶心一下死鬼佬。

经验总结:发现问题,首先应该查看日志。

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