i have a dream

i donn’t konw when i began to love traveing on the Google maps,i want to travel around the world,this is my greatest dream.

i left China for the first time in November 2013 to go to Singarpore,feels like this ongoing dream.Many things for the first time to me on this trip.such as my first flight,my first to go ot another country,a lot of things was new for me,i really like it.In Singarpore,i have to speak English,even though i can only speak a little English.it helps me realize that,English is very important.I must learn English well if i want to realize my dream.

So,i forced myself to reading more English books & technical documentation,learn more English words,listen to English songs,write something in English.i want to improve my English quickly,but it looks very difficult,so i have to make a little progress every day.

Traving on the Google maps,looking at some beautiful scenery,it gives me a lot of motivations.i believe that my dream will surely come true.

Getting started with Wechat

This week is about to end,it didn’t receive any email from DHL customers until now,so i am a little bit not used it.

The good news is I can spend more time to study some courses,such as Android or Wechat.i finished the WeChat Public Platform Development Best Practice,know more about Wechat developement and take some notes below.

How to create a Wechat test account?
Just go to http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login and click the login button,then use Scan QR Code functionality on you mobile phone to scan the QR on the desktop,it’s very easy.

How to set up URL & Token with your own server?
First,we should have our own server,and set up a can-access website as wechat developement project,like this http://wx.webtribe.com.cn.I set the URL to http://wx.webtribe.com.cn/api.php,then set the Token to webtribe,so the codes in api.php are:
[php]
/*
Webtribe http://www.webtribe.com.cn
Pengcheng 2016-05-12
*/

define(“TOKEN”, “webtribe”);
$wechatObj = new wechatCallbackapiTest();
if (isset($_GET[‘echostr’])) {
$wechatObj->valid();
}else{
$wechatObj->responseMsg();
}

class wechatCallbackapiTest
{
public function valid()
{
$echoStr = $_GET[“echostr”];
if($this->checkSignature()){
header(‘content-type:text’);
echo $echoStr;
exit;
}
}

private function checkSignature()
{
$signature = $_GET[“signature”];
$timestamp = $_GET[“timestamp”];
$nonce = $_GET[“nonce”];

$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );

if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}

public function responseMsg()
{
$postStr = $GLOBALS[“HTTP_RAW_POST_DATA”];

if (!empty($postStr)){
$postObj = simplexml_load_string($postStr, ‘SimpleXMLElement’, LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$time = time();
$textTpl = “


%s


0
“;
if($keyword == “?” || $keyword == “?”)
{
$msgType = “text”;
$contentStr = date(“Y-m-d H:i:s”,time());
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}
}else{
echo “”;
exit;
}
}
}
[/php]

How to get the Access Token?
Just request https://api.weixin.qq.com/cgi-bin/token with your appid and secret of you wechat test account,the final URL maybe is https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret,ok,let me share the codes to you.
[php]
$appid = “wx97fxxxxxxxx9bbda”;
$appsecret = “3efd14bcxxxxxxx38ade06cf697fc40”;
$url = “https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret”;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
$jsoninfo = json_decode($output, true);
$access_token = $jsoninfo[“access_token”];
echo $access_token;
exit;
[/php]

i have not finished wechat developement,will write more when i get more,so stay tuned!

Set email notification on Git commits

How do i configure the appropoiate Git hook to send a summary email whenever a set of changes is pushed to the repository?

There is a simplest solution:

  1. Go to one of your repository that you want to setup email notification.
  2. On the right menu,click on Settings,go to repository setting page.
  3. On the left options,click on Webhooks & Services.
  4. In the Services tab,click Add services,from available services,choose Email.
  5. Fill in your email address in field Address.
  6. Check the checkbox Sedn from Author & Active.
  7. Click the Add service button to complete the configuration.
  8. After setting,we can click the Test service button to send the test email.

This is my way to setup email notification. 🙂

jQuery Validate addMethod

在用jQuery Validate时,有时它提供的标准的验证规则也不一定能完全满足我们的业务需求。但是它提供了可自定义验证规则的方法addMethod。

如我们的客户DHL的员工号是是以14开头的8位数字,那么我们在使用jQuery Validate验证时,就可以这样自定义验证规则:

[js]
// Custom validation rule for DHL employee email
jQuery.validator.addMethod(“dhlEmpId”, function(value, element) {
return this.optional(element) || /^(14)[0-9]{6}$/.test(value);
}, “请输入8位员工号!”);
[/js]

其中:this.optional(element)的意思是出发这个规则的element的值为空时不触发验证,换句话说就是这个element的值可以不填,如果填了就不能填错格式。

如果想要这个element的值为空也要触发验证,直接把this.optional(element)去掉即可:return /^(14)[0-9]{6}$/.test(value);

当然你也可以在这个方法体内自己定义较复杂的规则,包含自己的业务逻辑,如下是一个天数的验证:

[js]
$.validator.addMethod(“validAvailDays”, function( value, element ) {
var courseAvailOption = $(“#quiz-basic-attr-form input[name=sb_course_avail]:checked”).val();
if(courseAvailOption == 2) {
var cknum = /^[1-9]\d*$/;
if(cknum.test($(“#sb_avail_days”).val())){
return true;
}
else{
return false;
}
}
else {
return true;
}
}, “天数限制必须是大于0的数字!”);
[/js]

js & jQuery验证Email

之前没有jQuery Validate这个插件,我们一般会用正则表达试来验证表单,检查用户输入的数据是否合法。

html代码如下:
[xhtml]



[/xhtml]

那js验证Email时就会像下面这样:

[js]
var emailStr = document.getElementById(“email”).value;
var emailRegex = /^([a-zA-Z0-9]+[|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[|_|.]?)*[a-zA-Z0-9]+.[a-zA-Z]{2,3}$/;
if(emailRegex.test(emailStr)){
console.log(“Your email is valid!”);
}
else{
console.log(“You email is invalid!”);
}
[/js]

接触jQuery Validate之后呢,验证Email就比较简单了:

[js]
$(document).ready(function() {
$(“#user-info-form”).validate({
rules: {
email: {
required: true,
email: true
}
},
messages: {
email: “请输入一个正确的邮箱!”
}
});
});
[/js]

cfscript 随机打乱数组元素顺序

前段时间有遇到这样的一个需求,原本给定一个数组,比如是:

array = [‘1′,’2′,’3′,’4′,’5’]

现在需要把数组里所有元素的顺序随机打乱,于是自己写了一个算法,分享出来。


	public array function sortQuestions( required array arrayOfQuesions){
		LOCAL.arrayOfSortedQuestion = [];

		numOfQuestions = arrayLen(ARGUMENTS.arrayOfQuesions);
		for (i=1; i<=numOfQuestions; i=i+1) {
			if(i == numOfQuestions){
				maxNum = 1;
			}
			else{
				maxNum = numOfQuestions - i + 1;
			}
			pos = randRange(1, maxNum);
			arrayAppend(LOCAL.arrayOfSortedQuestion, ARGUMENTS.arrayOfQuesions[pos]);
			arrayDeleteAt(ARGUMENTS.arrayOfQuesions, pos);
		}

		return LOCAL.arrayOfSortedQuestion;
	}

	writeDump(sortQuestions(['1','2','3','4','5']));

执行一次得出的结果是:
random_items

jQuery HTML clone

有时候我们会有这样的需求:

在HTML页面中单击一个按钮,某处表格会增加一行新的内容
如果使用js直接串HTML,在js代码里就会显得很乱
那么我们就可以用到jQuery的clone方法了

Step 1. HTML代码中添加Template
[xhtml]


[/xhtml]

Step 2. JS中可以这样获取HTML Template,并替换内容追加到现有的HTML后
[js]
var emailItem = $($(“script.template”).html()).clone();
emailItem.attr(“id”, userId);
emailItem.find(“td.name”).text(userName);
emailItem.find(“td.email input”).val(userEmail);
$(“#email-selected”).append(emailItem);

$(this).closest(“tr”).fadeOut(1000, function() {
$(this).closest(“tr”).remove();
});
[/js]

分享一些好的技术学习站点

不知不觉,身后也跟了几个做IT的,每个人基础和天赋不一样,学习态度也不一样,所以掌握的技术深度自然也就不一样了。

我刚走出培训学校参加工作的时候,觉得自己什么都不是。害怕所有的即将到来的工作自己Hold不住,所以除了每天正常的工作外,还会抽出时间学习新的知识。ColdFusion、Oracle、jQuery也都是在这段时间学习并了解的。

然后就一直在Webtribe了,跟着Alan学习了许多新的开发技术(如OOP)和工具(如Git),但学到的远远不止这些了,对我来说都是一生的财富。

闲话不多说了,自己Bookmark的东西开始放出,以后还会随时更新。其实这些东西Google一下就能很方便的找到了。

学习站点:

工具集:

技术类站点:

官方API文档:

看来自己的Bookmark也需要整理一下了,后续还会再补充:)

常用的cfscript snippets

现在自己写CFML程序,除非老的代码修改,已经不再使用Tags,基本上是用Script了。

有时候花了很长时间在Google或Stackoverflow上查到的cfscript snippets,是已经用到了项目上,但是没有记录,可能过了有一段时间,再有用到这写cfscript snippets时,绞尽脑汁去回忆之前用在什么地方。

这样,挺浪费时间的,于是有想法在此Post里记录下,用到的时候就直接来这里Copy了。懒人么,就是这样:)

setting

setting enablecfoutputonly="true" requesttimeout="150" showdebugoutput="false";

param

param name="form.role" type="string" default="user";

directory

if(!directoryExists(filesDir)){
	directory action="create" directory="#filesDir#";
}

if(directoryExists(empFilesDir)){
	directory action="delete" directory="#filesDir#" recurse="true";
}

transaction

transaction {
	try {
		// do something
		transaction action="commit";
	} catch (any e) {
		writeDump(e);
		transaction action="rollback";
	}
}

query insert

queryObj = new query();
queryObj.setDatasource(request.dsn);

queryObj.setName("qryName");
queryObj.setSQL("
	INSERT INTO table_name (
		name,
		age,
		status
	) VALUES (
		:name,
		:age,
		:status
	)
");
queryObj.addParam(name="name",value="#mid#",cfsqltype="cf_sql_varchar");
queryObj.addParam(name="age",value="#empId#",cfsqltype="cf_sql_integer");
queryObj.addParam(name="status",value="#status#",cfsqltype="cf_sql_varchar");
queryPrefix = queryObj.execute().getPrefix();
newId = queryPrefix.generatedKey;
queryObj.clearParams();

query delete

queryObj.setName("deleteUser");
queryObj.setSQL("
	DELETE FROM users
	WHERE id = :id
");
queryObj.addParam(name="id",value="#id#",cfsqltype="cf_sql_numeric");
queryObj.execute();
queryObj.clearParams();

query update

queryObj.setName("updateTbl");
queryObj.setSQL("
	UPDATE tbl SET
		page = :page,
		status = :status
		modified_date = GETDATE()
	WHERE id = :id
");
queryObj.addParam(name="page",value="#form.page#",cfsqltype="cf_sql_numeric");
queryObj.addParam(name="status",value="#form.status#",cfsqltype="cf_sql_varchar");
queryObj.addParam(name="id",value="#form.id#",cfsqltype="cf_sql_numeric");
queryObj.execute();
queryObj.clearParams();

query select

queryObj.setName("getStuDtl");
queryObj.setSQL("
	SELECT	*
	FROM	students
	WHERE	id = :stu_id
");
queryObj.addParam(name="id",value="#form.stu_id#",cfsqltype="cf_sql_integer");
qryStuDtl = queryObj.execute().getResult();
queryObj.clearParams();

coldfusion query of queries

queryObj.setName("getOldTeachers");
queryObj.setDBType("query");
queryObj.setAttributes(questions=qryAllTeachers);
queryObj.setSQL("
	SELECT	*
	FROM 	qryAllTeachers
	WHERE	age > :max_age
	ORDER BY id
");
queryObj.addParam(name="max_age",value="55",cfsqltype="cf_sql_integer");
qryOldTeachers = queryObj.execute().getResult();
queryObj.clearParams();