查看 Web应用 栏目文章
三月
6

安装配置ttserver(Tokyo Cabinet,Tokyo Tyrant) ttserver.c:611错误解决办法

Author Dominic    Category linux, Web应用     Tags ,

最近在尝试安装ttserver来评估一下用于某个SCADA中可行性,在CentOS 6.2下安装Tokyo Tyrant时使用下列命令时出现一个错误:

yum install tokyocabinet tokyocabinet-devel

wget http://fallabs.com//tokyotyrant-1.1.41.tar.gz

tar xvzf tokyotyrant-1.1.41.tar.gz

cd tokyotyrant-1.1.41

make

报错:tokyotyrant-1.1.41/.c:611: undefined reference to `tcadbsetskelmulti`。说是这个函数没有定义过,有人说直接把代码注释掉,这样做不太好。经过查询原来版本兼容性问题。

tcadbsetskelmulti 这个函数是Tokyo Cabinet 1.4.35版本中引入的新函数,这一点可以冲tokyocabinet的ChangeLog中发现,同时加入的新函数还有tcadbmulnew, tcadbmuldel,setskeltran。所以为了使用TokyoTyrant 1.1.41必须使用1.4.35版本及之后的Tokyo Cabinet,那么就换最新版本的Tokyo Cabinet吧。

yum install gcc-c++ zlib-devel bzip2-devel

wget http://fallabs.com/tokyocabinet/tokyocabinet-1.4.47.tar.gz

tar xvzf tokyocabinet-1.4.47.tar.gz

cd tokyocabinet-1.4.47

./configure –enable-profile

make

make install

cd

wget http://fallabs.com/tokyotyrant/tokyotyrant-1.1.41.tar.gz

tar xvzf tokyotyrant-1.1.41.tar.gz

cd tokyotyrant-1.1.41

./configure

make

make install

果然顺利安装ttserver

七月
4

用Postgresql作为BIND9 数据存储情况下TXT等包含空格记录的处理

Author Dominic    Category linux, Web应用     Tags , ,

前段时间尝试用PostgreSQL 作为BIND9的后端数据存储玩玩,发现真不错,需要的Postgresql数据库表结构简单,查询效率高、及时生效。SOA记录也是一条语句,但发送邮件需要的TXT记录出现了问题,按照SPF格式写入了以下TXT记录:“v=1 ip4:60.166.118.xxx include:xuplus.com -all”,结果使用nslookup查询出来的情况竟然是这样的:

服务器:  google-public-dns-a.google.com
Address:  8.8.8.8

非权威应答:
xuplus.com      text =

        "v=spf1"
        "ip4:60.166.118.xxx"
        "include:xuplus.com"
        "-all"

这样的记录是没有办法使用的,使用SPF记录测试工具(http://www.openspf.org/Tools)是没有办法通过。查阅了一番资料发现无法解决这个问题,翻阅bind9 源代码发现在rdata.c文件的dns_rdata_tofmttext函数中使用了的linebreak就是空格字符,那么向spf这种需要包含空格的记录怎么办呢?经过尝试可以添加斜线(\)作为转义字符,由于数据库记录中斜线也需要转义,所以将记录对应的rdata字段值改成 ‘v=spf1\\ ip4:60.166.118.xxx\\ include:xuplus.com\\ -all’这样的即可,这样之后再次nslookup就可以发现结果正常了:

服务器:  cache2.ahwhtel.net.cn
Address:  202.102.199.68

非权威应答:
xuplus.com      text =

        "v=spf1 ip4:60.166.118.xxx include:xuplus.com -all"

xuplus.com      nameserver = dns2.xuplus.com
xuplus.com      nameserver = dns1.xuplus.com
dns1.gi-rms.com internet address = 60.166.118.xxx
dns2.gi-rms.com internet address = 60.166.118.xxx

9也有转移字符:斜线(\)。

三月
26

给CodeIgniter 2.0.1中的PostgreSQL 数据库驱动打两个补丁

Author Dominic    Category PHP     Tags ,

近期帮朋友用CodeIgniter基于PostgreSQL做了个小东西,发现CodeIgniter2.0.0在实现PostgreSQL数据库驱动是有两个小缺陷。

一个是CI的数据库通用接口insert_batch,CI2.0发布包中的PosgreSQL驱动实现,并没有实现该接口,可以在system\database\drivers\postgre\postgre_driver.php文件中的_insert函数下添加如下函数。

// -------------------------------------------------------------------- /** * Insert_batch statement * * Generates a platform-specific insert string from the supplied data * * @access public * @param string the table name * @param array the insert keys * @param array the insert values * @return string */ function _insert_batch($table, $keys, $values) { return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values); } // --------------------------------------------------------------------

另一个是insert_id()函数,该函数如果在数据表没有serial字段可能无法返回数值,导致问题,特别是主从表而从表不需要serial字段的情况下。

如果碰到这个问题可以把原来的:

elseif ($table != null && $column != null && $v >= '8.0') { $sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column); $query = $this->query($sql); $row = $query->row(); $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq); }

修改成:

elseif ($table != null && $column != null && $v >= '8.0') { $sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column); $query = $this->query($sql); $row = $query->row(); if($row->seq!='') $sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq); else $sql='SELECT LASTVAL() as ins_id'; }

一月
18

CentOS下redmine、apache、svn配置安装心得

Author Dominic    Category Web应用, 软件应用     Tags , ,

CentOS默认开启了SELinux,安装Redmine、apache、svn之类的还是蛮复杂的,经过几次折腾之后,终于顺利将redmine折腾成功了,有些心得记录下来备查:

集成方案大体为:

a) svn和apache集成,通过http协议访问svn,svn使用域名svn.test.com,仓库访问路径为:http://.test.com/XXXX

b) svn通过Perl和redmine的数据库集成提供身份和权限认证,仓库访问用户名和密码由redmine中创建的用户和密码访问,可访问项目仓库受redmine控制

c) redmine用mongrel_rails 运行于3000端口

d) apache使用proxy模块将pms.image-pro.com.cn的80端口反向代理到redmine的3000端口

e) 每5分钟通过cron的形式将redmine中项目信息同步到svn中

1、不要使用passenger集成Apache,使用反向代理方式集成Apache

官方指南中使用passenger来和Apache集成,但是passenger跟SELinux集成是很困难正常运行的,解决办法需要将SELinux更改为permissive模式(编辑

/etc/sysconfig/selinux文件修改为SELINUX=permissive),然而使用Apache的反向代理向rails转发却简单得多。

这种方式需要开启redmine的“启用用于版本库管理的Web Service”功能,设置方式为安装完成之后,用admin账号登陆redmine,进入“管理”->“配置”->“版本库”设置页面开启“启用用于版本库管理的Web Service”选项,并生成一个API Key,这个API key有用。

相关virtualhost配置节点如下:

<VirtualHost *:80> ServerAdmin bbs@test.com DocumentRoot "/var/www/" ServerName pms.test.com ErrorLog "logs/pms.test.com-error.log" CustomLog "logs/pms.test.com-access.log" combined <Location /sys> Order deny,allow Allow from 127.0.0.1 Deny from all </Location> ProxyPass / http://localhost:3000/ ProxyPassReverse / http://localhost:3000/ </VirtualHost>

注意:如果/etc/hosts文件中没有解析相关域名到127.0.0.1的话,最好在Allow from后面添加一行让服务器ip可以正常访问。

2、使用两个virtualhost,分别安装redmine和svn,并使用一个location配置svn

这样的好处是明显的,svn单独访问也足够间接,不使用svn和svn-private两个Location配置来分别供给SVN客户端和redmine使用。

相关virtualhost配置节点如下:

<VirtualHost *:80> ServerAdmin svn@test.com ServerName svn.test.com ErrorLog "logs/dummy-svn.test.com-error.log" CustomLog "logs/dummy-svn.test.com-access.log" combined PerlLoadModule Apache2::Redmine <Location /> DAV svn SVNParentPath "/var/svn" Order deny,allow Deny from all Satisfy any PerlAccessHandler Apache::Authn::Redmine::access_handler PerlAuthenHandler Apache::Authn::Redmine::authen_handler AuthType Basic AuthName "Redmine SVN Repository" #read-only access <Limit GET PROPFIND OPTIONS REPORT> Require valid-user Allow from 127.0.0.1 # Allow from another-ip Satisfy any </Limit> # write access <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept> ## for mysql RedmineDSN "DBI:mysql:database=redmine;host=localhost" RedmineDbUser "redmine" RedmineDbPass "password" </Location> </VirtualHost>

这里Allow from跟上面说的一样,最好添加服务器的ip通过,这样一个Location节点即可完成SVN设置,保证redmine中看到的svn仓库地址和SVN客户端(例如:TortoiseSVN)中使用的svn仓库地址一致(都是http://svn.test.com/XXXXX,而不是一个/svn-private/XXX,一个/svn/XXXX),而且svn仓库地址也够简洁。

3、如果邮件使用GMail的服务,则需要使用ruby 1.8.7,rails要求2.3.5

如果默认安装的是ruby 1.8.6则发送邮件的时候会报错,要求先自行starttls命令。必须升级到1.8.7

相关命令:

ftp ftp.ruby-lang.org cd /pub/ruby get ruby-1.8.7.pXXX.tar.gz tar zxvf ruby-1.8.7.pXXX.tar.gz ruby-1.8.7.pXXX cd ruby-1.8.7.pXXX ./configure --prefix=/usr make make install ruby -v which ruby cd ..

这里XXX是对应的发布版本号,当前是330,需要注意的是有些版本不一定能够正常编译通过,我在测试的时候p160编译就通过不了。

4、相关SELinux权限设置

执行以下命令赋予相关目录正确的SELinux属性:

chcon -u system_u -R -t httpd_log_t /var/www/redmine/log chcon -u system_u -R -t httpd_tmpfs_t /var/www/redmine/tmp chcon -u system_u -R -t httpd_sys_script_rw_t /var/www/redmine/files chcon -u system_u -R -t httpd_sys_script_rw_t /var/www/redmine/public/plugin_assets

由于svn版本库的SELinux设置比较复杂,可以通过以下命令直接处理完毕

chcon -u system_u -R -h -t httpd_sys_script_rw_t /var/svn

5、redmine跟svn之间有关版本库通过可以通过cron来完成

cron执行内容如下:

0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/bin/ruby /var/www/redmine/extra/svn/reposman.rb --redmine pms.test.com -k apikey --svn-dir /var/svn --owner apache --url http://svn.test.com/ >> /var/log/reposman.log

其中apikey内容为redmine后台生成的API key,这样每5分钟都会将redmine中的版本库信息同步到svn中(自动创建版本库)

6、redmine使用mongrel自启动

安装mongrel之后,使用cron来确保在启动时候自动启动mongrel_rails来启动redmine。

cron执行内容如下:

@reboot cd /var/www/redmine; rm -f log/mongrel.pid; /usr/bin/mongrel_rails start -p 3000 -d -e production

7、使用ImageMagick绘制甘特图,需要rMagick 1.5.17版本

执行以下命令:

yum install ImageMagick -y yum install ImageMagick-devel -y yum install freetype -y yum install gd-devel -y wget http://www.osresources.com/files/centos-windows-fonts/msfonts.tbz mkdir /usr/share/fonts/default/TrueType tar xvjpf msfonts.tbz -C /usr/share/fonts/default/TrueType/ gem install rmagick -v=1.15.17

8、Redmine.pm存放文字需要根据实际情况来定

x64位操作系统perl库文件位置是/usr/lib64/perl5下,perl5.10版本库位置不再是/perl5.8.8,最后位置也不一定是Apache目录,例如:我机器上就是复制到/usr/lib64/perl5/Apache2目录下,所以具体目录应该根据实际情况决定,拷贝完毕之后Apache的相关VirtualHost配置加载的模块语句就有变化了(如上我的变成了Apache::Redmine)。

 

整体来说,安装过程需要仔细,特别是SELinux在某种程度上来说是设置的羁绊,但RedHat等公司开发它肯定有他的安全必要性,所以我们还是完成SELinux环境下安装比较好。

相关可参考官方资源和文档:

Installing Redmine:http://www.redmine.org/projects/redmine/wiki/RedmineInstall

How To Automate repository creation:http://www.redmine.org/projects/redmine/wiki/HowTo_Automate_repository_creation

Repositories access control with apache, mod_dav_svn and mod_perl:http://www.redmine.org/projects/redmine/wiki/HowTo_configure_Redmine_for_advanced_Subversion_integration

Email Configuration:http://www.redmine.org/projects/redmine/wiki/EmailConfiguration

, Subversion and mod_svn:http://ejohansson.se/archives/2007/11/04/selinux-subversion-and-mod_svn/

一月
4

PayDollar支付通道开发介绍及ECShop开发PayDollar注意事项

Author Dominic    Category Web应用     Tags ,

前些时候帮助一个香港朋友开发了ECShop的支付插件,他们使用PayDollar支付网关。

www.paydollar.com联款通有限公司成立于2000年,是领先的世界级电子付款及移动付款解决方案与技术提供应商,亦是香港最大第三方支付平台之一。

「传款易支付网关」是一个完善、综合、安全及提供实时交易的平台,可供银行或支付处理服务机构架设一个可支持多种支付方式的收付款服务,帮助提高商户销量及生产力。

「传款易支付网关」能处理不同渠道的实时支付交易,如网络支付及移动设备支付。也能提供界面连接到各种支付系统主机作为支付授权和结算。

核心功能

  • 支持多语言和多支付模式,提供各类完整的报告
  • 支持多支付模式如:网上交易、离线交易、其他定制化的支付交易
  • 便捷架设及提供多商户连接界面
  • 灵活选择独立支付界面或后端连接界面,商户无须额外投资任何软件

支付方式

  • VISA / 万事达咭 / 大来信用证JCB 本地银行户口付款 (如PPS)

交易功能

  • 通过网络及移动设备进行电子商务、移动商务、邮购及电话购物
  • 实时撤销及处理退款要求
  • 手动、自动或整批结算选择

电子邮件通知功能

  • 综合商户帐户让商户可以通过不同渠道进行交易管理
  • 完善的交易报告显示销售状况
  • 单笔交易或整批交易资料下载

控制功能

  • 多层式用户群控制管理,可供银行或商户使用
  • 提供安全管理网站给银行及商户
  • 指定商户每比、每日、每月的金额上限
  • 风险控制工具包括:阻挡负面IP及信用卡的交易、实时交易检查及风险警示功能

安全功能

  • 采用128位SSL加密装置
  • 资料库加密
  • 支持VISA验证、SecureCode认证JCB/Jsecure认证服务
  • PayAlert(实时交易风险检查)

其他增值功能

  • 循环支付设定及管理
  • 自建购物网站和购物交易管理

界面标准

  • 支持ISO 8583和SSL银行支付连接界面

 

总之,在香港它就是像支付宝、快钱这样的第三方支付平台,可对大陆客户提供中国银联网上支付平台、支付宝平台、财付通平台、快钱平台、PayPal平台支付以及Visa、MasterCar、JCB等信用卡直接扣帐支付的一个综合支付交易平台。应该是香港商家对大陆客户提供服务的可靠支付通道。

如果有碰到有朋友或者客户需要使用PayDollar支付平台可以参考一下内容:

一般香港商户在完成在香港的银行开户之后,可以接洽PayDollar,PayDollar之后会发送一个CheckList让香港商户去准备,要求做到以下几点:

  1. 一个商户自己的页面(一般有网站即可);
  2. 在页面底部放入PayDollar和相应需要支付平台的Logo(PayDollar必须放,其他Logo要看香港商户跟PayDollar的谈判,如果只有银联平台则只放PayDollar和银联的Logo);
  3. 提供一个包含交易货币的有关货物和服务的描述页面;
  4. 提供一个描述退换货、货物配送、使用条款的页面;
  5. 提供一个公司联系方式信息页面,至少包含公司地址、email地址和电话号码;
  6. 提供一个页面描述支付卡交易策略和安全保障措施(例如:SSL和数据加密,他们会给一个范例);
  7. 提供一个页面描述顾客数据隐私保护策略(例如:Cookies);
  8. 一个购物车

其中,很多条款他们都提供了参考页面,购物车可以实现也可以不实现,只要有购买页面即可。就是为了满足这个需要踩帮助香港的朋友使用了ECShop,谁知道ECShop并没有PayDollar支付插件,网上可以找到一些PayDollar的支付代码(ShopEx的插件代码),但是已经不能和PayDollar现在的支付网关适应了。

准备好之后,PayDollar会开通商户的支付功能,并提供一个商户号(Merchant Id),我们还需要发送邮件到service@paydollar.com,要求开通商户帐号的哈希码安全认证功能(为了确保支付安全还是开通了好)

在给ECShop开发PayDollar支付插件有以下几个问题树妖注意:

  1. PayDollar对于每一个币种都是单独的商户号也对应不同的哈希码安全认证;
  2. PayDollar现在支持哈希码安全认证功能,且哈希算法变成了SHA1,哈希码安全认证有效期两年;
  3. PayDollar的跳转商户页面和PayDollar返回支付成功信息页面是两个页面;
  4. PayDollar有关哈希码安全认证功能中各个参数有变化(相对网上可以搜索到的ShopEx的插件代码),连接字符串已经变成了竖线|而不是&符号;
  5. 提供给PayDollar的交易返回页面是需要在PayDollar管理系统中设置的,而不是在代码中指定的,PayDollar是通过Post方法来将数据提交到这个指定URL;
  6. 如果不是使用Client通过浏览器Post的方式支付,则需要自己实现支付页面(可自己实现信用卡信息填写页面,做3DS验证)。

在给ECShop开发插件过程中我给上面第三条和第五条搞败了,ECShop接收返回信息是通过/respond.php文件再调用includes/modules/payment/paydollar.php中的respond()方法的,开始的时候我并不知道这样,这样直接导致需要单独给一个文件给PayDollar来处理支付通知信息,respond()方法中只提供支付成败信息然后让respond.php输出支付成败提示信息,respond.php文件还一定得显示respond.dwt这个Smarty模板文件。为了偷懒,我在在respond()方法中通过判断回传参数来区分是PayDollar直接跳转的还是Post回传的。设置PayDollar系统中返回链接方式如下:

登录PayDollar之后,在“商家资料”页面,点击“支付选项”,进入设置页面,填入对应的链接地址,选中右侧的“可用”,点击“更新”按钮再在后续页面点击“确定”按钮即可,如下图:

paydollar_setting

这样就可以正常实现支付了。附件中是PayDollar集成开发的文档,仅供参考,文档主要有:

├─开源购物车插件 │ Magento PayDollar_v1.zip │ OpenCart PayDollar_v148b.zip │ oscommerce paydollar v2.3.zip │ PayDollar_开源购物车集成指南_v2.pdf │ VirtueMart_PayDollar.zip │ virtuemart_payment_extra_info.txt │ ZenCart paydollar_payment_module_1-0.zip │ ├─技术文档 │ 付款流程概述.pdf │ 传款易定时付款用户指南SchedulePay_V1.6.pdf │ 传款易批事务处理用户指南V1.0.pdf │ 传款易集成指南 _v3.7_.pdf │ ├─接口代码例子 │ asp_DirectClientPost.zip │ asp_SimpleClientPost.zip │ Csharp_DirectClientPost.zip │ Csharp_DirectServerSide.zip │ Csharp_SimpleClientPost.zip │ java_DirectClientPost.zip │ java_DirectServerSide.zip │ java_SimpleClientPost.zip │ php_DirectClientPost.zip │ php_DirectServerSide.zip │ php_SimpleClientPost.zip │ └─文件 Bank required checklist items.pdf FAQ_for_Alipay_By_PayDollar.pdf Logo使用说明.txt PayDollar_商户操作指南_v3-5.pdf PayDollar_操作指南.pdf 退款手续_v1.pdf

下载地址:PayDollar集成资料.rar

十一月
17

Drupal6中启用文章内容多语言支持的方法

Author Dominic    Category Drupal     Tags ,

这两天尝试Drupal6,想分析看一下Drupal6中对于多语言内容是如何支持的?参照了网上hsiao blog的一系列文章:
durpal建设多语言站点之一
drupal建立多语言站点之二:使用Localization client模块
durpal建立多语言站点之三:内容多语言
drupal建设多语言站点之四:不同语言的站点名称

但是他的文章主要描述了站点多语言的支持“durpal建立多语言站点之三:内容多语言”这篇文章却并没有讲解怎么开启内容多语言,第二幅图片中却有“Translate”的链接。相当奇怪!

6中包含了Content Translation模块,该模块允许网站内容翻译成不同语言,它和本地化模块 (Locale模块,负责管理多语言,并提供多语言网站翻译接口)协同工作,它是创建和维护多语言内容站点的关键。Drupal默认并没有开启该模块功能,要正确开启该模块功能,需要进行以下操作:

  1. 在站点构建中的模块管理中启用“Content translation”模块,如果安装列i18n模块,建议同时启用“Content type translation”模块;
  2. 在“权限”配置页面权限给适当的用户角色分配“翻译内容”权限;
  3. “语言”的配置页面中新增并启用的所需要的语言;
  4. 在管理->内容管理->内容类型页面中,点击要支持多语言功能的内容类型(例如:Page和Story)右侧的“编辑”按钮,然后在“流程设置”折叠框中的“多语言支持”选中“启用,与翻译一起”。

这样在创建或者编辑文章的时候会出现一个语言下拉框和翻译链接,如下图:

image

点击“翻译”链接进入翻译查看页面可以看到如下页面:

image

点击旁边“添加翻译”链接或者“编辑”页面就可以进入其他语言内容编辑页面了。

三月
28

Xoops中获取模块配置参数的方法。

Author Dominic    Category XOOPS     Tags ,

Xoops群(53219504,17380705)中有人询问在开发的时候,怎样获取在xoops_version.php中添加的参数值。其实Xoops中统一管理模块的参数是非常好的一种做法(将在下一个平台性项目中借鉴这个做法),获取的方法也非常简单,针对不同的情况可以分别实现如下:

1、更改现有模块代码,且现有模块代码中包含了全局性变量$xoopsModuleConfig的情况

这种情况比较简单:

global $xoopsModuleConfig;
$configvalue=$xoopsModuleConfig["xxxx"];
//xxxx为xoops_vesion.php中定义的参数对应名称

2、现有模块代码中不包含$xoopsModuleConfig或者自行开发简单模块且不使用Framework

$module_handler = &_gethandler('module');//获取module句柄$module_handler
$module = $module_handler->getByDirname("xxx");//xxx为模块目录名称,获取特定module操作句柄$module
$config_handler = &xoops_gethandler('config');//获取config的句柄$config_handler
$criteria = new CriteriaCompo(new Criteria('conf_modid', $module->getVar('mid')));// 根据上述module的id构建查询参数$criteria
$configs =& $config_handler->getConfigs($criteria);//用config句柄获得特定module的参数配置结果集

foreach(array_keys($configs) as $i)
{
$moduleConfig[$configs[$i]->getVar('conf_name')] = $configs[$i]->getConfValueForOutput();//转化成数组
}
unset($configs);

之后直接使用$moduleConfig['xxxx']就可以访问了,也可以把$moduleConfig设置为全局变量。

3、使用Framework的模块

load_functions("config");
$moduleConfig = mod_loadConfg("moduledirname");

使用Framework的情况可以参考article中代码。

十二月
27

[Hack]Xoops中article模块分类显示页面同时显示子分类文章的方法

Author Dominic    Category XOOPS     Tags , ,

D.J.老大的article模组确实好用,但是在分类文章列表显示页面view.category.php这个文件中却只显示给定栏目ID的文章和子分类列表及子分类文章数。虽然个人比较喜欢这种方式,但这种方式并不适合目前国内流行文章管理系统在显示栏目的文章方式,一般的网站在现实栏目时需要将分类的子分类文章也同时显示出来。

针对目前大多数都是采用两级分类的方式,我对view.category.php做了一些Hack:

1、在view.category.php 97行附近修改如下:

$counts_category =& $category_handler->getCategoryCounts(array_keys($categories), "access");
    //Add By XuYong 获取子栏目下给定篇数文章

    $articles_perpage = (empty($start) && empty($list)) ? $xoopsModuleConfig["articles_category"] : $xoopsModuleConfig["articles_perpage"];
    //End Add

foreach( $categories as $id=>$cat){
    //Add By XuYong 获取子栏目下给定篇数文章
    $subcriteria = new CriteriaCompo(new Criteria("ac.ac_publish", 0, ">"));
    $subarticle_id =& $article_handler->getIdsByCategory($cat, $articles_perpage, 0, $subcriteria);
    if(count($subarticle_id)>0){
        $criteria = new Criteria("art_id", "(".implode(",",$subarticle_id).")", "IN");
        $tags = array("uid", "writer_id", "art_title", "art_summary", "art_image", "art_pages", "art_categories", "art_time_publish", "art_counter", "art_comments", "art_trackbacks");
        $subarticles_obj =& $article_handler->getAll($criteria, $tags);
    }else{
        $subarticles_obj = array();
    }

    $subcatarticles = array();
    foreach ($subarticle_id as $id) {
        $_article = array(
            "id"        => $id,
            "title"        => $subarticles_obj[$id]->getVar("art_title"),
            "time"        => $subarticles_obj[$id]->getTime($xoopsModuleConfig["timeformat"]),
            "image"        => $subarticles_obj[$id]->getImage(),
            "counter"    => $subarticles_obj[$id]->getVar("art_counter"),
            "comments"    => $subarticles_obj[$id]->getVar("art_comments"),
            "trackbacks"=> $subarticles_obj[$id]->getVar("art_trackbacks")
            );
        if(!empty($xoopsModuleConfig["display_summary"])){
            $_article["summary"] = $subarticles_obj[$id]->getSummary(true);
        }
        $subcatarticles[$id] = $_article;
        unset($_article);
    }

    //End Add
    $subcategories[] = array(
        "id"            => $cat->getVar("cat_id"),
        "title"            => $cat->getVar("cat_title"),
        "articles"        => @intval($counts_article[$cat->getVar("cat_id")]),
        "categories"    => @intval($counts_category[$cat->getVar("cat_id")]),
        "subcatart"  => $subcatarticles
        );
        //Add By XuYong 获取子栏目下给定篇数文章
        unset($subcatarticles);
        //End Add
}
unset($criteria);
$criteria = new CriteriaCompo(new Criteria("ac.ac_feature", 0, ">"));
$criteria->setSort("ac.ac_feature");

2、修改模板文件article_category.html文件,134行附近修改如下:

<{if count($categories) gt 0}>
<div id="category" class="article-category">

    <{foreachq item=cat name=cat from=$categories}>
    <div class="category-header tdbg4" stype="width:80%">
<span class="sizscolor"><b><a href="<{$_url}>/modules/<{$_dirname}>/view.category.php<{$smarty.const.URL_DELIMITER}>c<{$cat.id}>/list"><{$cat.title}></a></b></span>
    </div>

        <{if count($cat.subcatart) gt 0}>
        <div id="article_<{$cat.id}>" class="article-article">
                    <table width="95%" border="0" align="center" cellspacing="0">
                        <{foreachq item=article from=$cat.subcatart}>
                      <tr class="tdlist">
                        <td  width="86%" height="24" class="tdlist">·<a href="<{$xoops_url}>/modules/<{$xoops_dirname}>/view.article.php<{$smarty.const.URL_DELIMITER}><{$article.id}>"><{$article.title}></a>
                                        <{if $article.image}><img src="<{$xoops_url}>/modules/<{$xoops_dirname}>/images/image.gif" width="12px" alt="" /><{/if}>
                        </td>
                        <td width="14%" height="2" class="tdlist"><{$article.time|date_format:"%y-%d-%m"}></td>
                      </tr>
                      <{/foreach}>
                                </table>
        </div>
        <{/if}>
            <div class="article-section-title">
            <span class="subject"> </span>
            <span class="navigation"><a href="<{$xoops_url}>/modules/<{$xoops_dirname}>/view.category.php<{$smarty.const.URL_DELIMITER}>c<{$cat.id}>/list"><{$smarty.const._MORE}></a>
            </span>
            </div>
            <div class="clear"></div>
    <{/foreach}>

</div>
<{/if}>

其中有些样式和一些修改是根据当前需要改的,需要根据自身情况调整。

效果demo;

view_category_hack_demo

 

Hack后的iview.category.php和模板文件下载:

十二月
26

Xoops中weblinks模组1.13版简体中文UTF8字符集乱码解决及语言包

Author Dominic    Category XOOPS     Tags , ,

今天xoops.org.cn上有人说道weblinksV1.13版本在用UTF8字符集的时候碰到乱码和RSS、ATOM输出乱码的问题,发现手上的一个小东西也存在这样的问题,虽然weblinks模组现在http://ohwada.net推出了1.82.1版本的weblinks模组,但需要装他们的happy_linux模组,而且目前还没有一个简体中文语言包,也就不想升级到新的weblinks模组了。在培训的间隙,花了点时间分析了以下问题,然来是从简体中文gb2312字符集语言包转换成UTF8语言包时候,虽然可以使用了,但是缺少了关键的UTF8转换处理函数(UTF8是不需要再转换的),导致本身就是utf8的字符串被二次编码,就导致乱码了。

解决办法是在weblinks_language_convert.php文件中加入utf8转换函数。需要清除cache目录中对应的缓存文件。

 

//Add By Xuyong
// 字符集不需要转化
//End Add
function convert_from_utf8($text)
{
    return ($text);
}
function convert_to_utf8($text)
{
    return ($text);
}

完整utf8语言包:

十二月
8

hibernate.cfg.xml位置及JDBC配置

项目需要构建一个Java环境,使用Hibernate作为数据持久层,一兄弟按照网上的说法配置了hibernate,结果搞了几天都没搞好,总是报错“Could not find datasource”,最后还是我自己动手在自己机器上配个环境才引导他弄好。

要配好Hibernate首先的弄清楚Java在寻找hibernate.cfg.xml这个文件的时候在哪些目录中寻找,Java将在以下目录中寻找hibernate.cfg.xml这个文件:
webappsname/WEB-INF/classes/
TOMCATHOME/
TOMCATHOME/lib

所以我们的hibernate.cfg.xml务必放在webapp的WEB-INF/classes/目录下了,放在其他目录下都不是很合适。

另外就是关于hibernate.cfg.xml中的jdbc配置了,网上的说法各异,其实最简单的就是在hibernate.cfg.xml中直接使用jdbc配置了,如下:
<?xml version=”1.0″  encoding=”utf-8″?>
<!DOCTYPE -configuration PUBLIC “-///Hibernate Configuration DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”>
<hibernate-configuration>
    <session-factory>
        <property name=”hibernate.connection.driver_class”>com.mysql.jdbc.Driver</property>
        <property name=”hibernate.connection.url”>jdbc:mysql://localhost/test</property>
        <property name=”hibernate.connection.username”>root</property>
        <property name=”hibernate.connection.password” />
        <property name=”show_sql”>false</property>
        <property name=”dialect”>org.hibernate.dialect.MySQLDialect</property>
        <mapping resource=”hb/Cat.hbm.xml” />
    </session-factory>
</hibernate-configuration>

更改其中的driverclass和connection.url、username、password和dialect,再添加一些mapping就可以了,需要注意的是property节点的name属性中最好在前面加上hibernate。有些文章说使用Tomcat的JNDI,不建议这么做。同时要注意的是在hibernate.cfg.xml不要同时使用datasource和连接字符串两种配置(那个兄弟非要使用两种配置结果来不成功),因为没有必要。

其实从部署的角度来看的话,就应该是这样的,首先在生产环境下,很多时候是没有办法拿到Tomcat的管理权限的是配不了JNDI的,而且要去配JNDI无形增加的部署的难度,在hibernate.cfg.xml中配置连接字符串就很方便部署(Hibernate要是像.net中那样支持连接字符串加密就好了)。hibernate.cfg.xml存放的位置也是一样的,放在WEB-INF/classes/目录下,部署的时候只要拷贝webapp整个目录就可以完成部署了。

网上的文章用来做参考最好,很多东西还得靠自己领会,特别是碰到问题的时候,尽心书不如无书嘛(也别太相信我写的,说不定那天不管用了。^_^)。

附:使用Tomcat JNDI 数据源配置方法
<?xml version=”1.0″  encoding=”utf-8″ ?>
<!DOCTYPE hibernate-configuration PUBLIC “-//Hibernate/Hibernate Configuration DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”>
<hibernate-configuration>
    <session-factory>
        <property name=”hibernate.connection.datasource”>java:comp/env/jdbc/odbcq</property>
        <property name=”show_sql”>false</property>
        <property name=”dialect”>org.hibernate.dialect.MySQLDialect</property>
        <mapping resource=”hb/Cat.hbm.xml” />
    </session-factory>
</hibernate-configuration>

专题推荐

标签

分类目录

新浪微博

存档

近期文章

近期评论

友情链接

分享按钮