Archive for August, 2008

Joomla 1.5.x remote admin password change

Saturday, August 16th, 2008

1 bug củ có thể nói là làm “bẽ mặt” Joomla team. Không thể ngờ Joomla lại có thể dính 1 lỗi chuối đến như vậy :-o

Thử với 1 site sử dụng Joomla version 1.5.2, mất 3 thao tác để vào được khu vực dành cho administrator :-T

Việc tiếp theo là thông báo bug cho ông anh admin với lời nhắn nhủ sau này em chụp ảnh cưới thì anh miễn phí cho em nhé – site kinh doanh áo cưới, ảnh cưới mà. Ông ấy đồng ý cái roẹt, sẽ free với điều kiện chú cưới lần 2 :) ) Nham hiểm thế ko biết.

Kinh nghiệm rút ra:
- Khi setup 1 site, sử dụng os, phải bỏ hết các default setting đi.
- Với admin area, nên cho thêm 1 access layer nữa (.htpasswd chẳng hạn).

Line endings

Wednesday, August 13th, 2008

Thỉnh thoảng bị gặp lỗi rất củ chuối với các ký tự new line :( Do có sự khác biệt với mỗi hệ điều hành nên cần check cẩn thận:

  • Dos/Windows: \r\n
  • Unix: \n
  • Mac: \r

Tham khảo thêm tại: http://en.wikipedia.org/wiki/Line_endings

Export to CSV file with Unicode

Monday, August 11th, 2008

Ở bài trước tôi có đề cập đến việc export dữ liệu ra file CSV. Tuy nhiên, nếu export dữ liệu có chứa các ký tự Unicode thì sẽ không hiển thị được mặc dù khi mở bằng Notepad thì vẫn hiển thị đúng, tuy nhiên khi mở bằng Excel thì không hiển thị chính xác. Search trên mạng thấy giải pháp của anh Nguyễn Văn Hùng (Hưng?) đã giải quyết được (tôi mới test với German characters trong dự án Shop24 – rất okie).

Bài toán: export dữ liệu tiếng Việt UTF-8 thành file CSV có thể hiển thị đúng khi mở bằng Excel.
3 điểm dẫn đến thành công:
+ Dùng TAB (\t) thay cho COMMA (,) để phân tách các cột
+ Convert Encoding của dữ liệu cần output bằng UTF-16LE
+ Gắn chr(255)chr(254) vào đầu của kết quả cuối cùng trước khi output

PHP code đầy đủ (export order list):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
 * EXPORT ORDER LIST TO CSV FILE
 * @author khanhdn
 */
function exportCSV() {
	global $user;
	member_access();
 
	$memberInfo = member_info();
 
	$result = drupal_query("SELECT order_id
					,order_code
					,bill_firstname
					,bill_lastname
					,order_modify_date
					,gand_total
					,order_status
					 FROM {order}
					 WHERE shop_code = '".$memberInfo['shop_code']."'
					 ORDER BY order_creation_date DESC");
 
	$status_options = array(
                                '1'  => 'Neu'
				,'2' => 'In Bearbeitung'
				,'3' => 'Auf der Post'
				,'4' => 'Ausgeführt'
				,'5' => 'Zurück'
				);
 
	$csv = "Order code\tCustomer Name\tModify Date\tOrder Total\tOrder Status\r\n";
 
	if(count($result['data']))
	{
		foreach($result['data'] as $row)
		{
			$order_list = array(
							'order_code' 		=> "$row->order_code"
							,'customer_name' 	=> $row->bill_firstname. ' ' .$row->bill_lastname
							,'modify_date' 		=> mysqlTimestamp(strtotime($row->order_modify_date),'d.m.Y')
							,'order_total'		 => 'CHF '.$row->gand_total
							,'order_status'		=> $status_options[$row->order_status]
			);
 
			$csv .= join("\t", $order_list)."\r\n";
		}
 
	}
	$csv = chr(255).chr(254).mb_convert_encoding($csv, "UTF-16LE", "UTF-8");
 
	header("Content-type: application/x-msdownload");
	header("Content-disposition: csv; filename=" . date("Y-m-d") .
	"_order_list.csv; size=".strlen($csv));
	echo $csv;
	exit();
}

Source: Nguyễn Văn Hùng weblog

Cài thêm 1 số plugin cho website

Sunday, August 10th, 2008

Hôm nay cài thêm mấy plugins sau cho website:D

  1. Subscribe to Comments
  2. Contact form
  3. PostRate

PHP session in Drupal

Thursday, August 7th, 2008

Ít nhất 2 lần tôi đã từng sống dở chết dở với vấn đề chết session trong Drupal. Đang chạy ngon lại lăn đùng ra chết. Qua tìm hiểu mới biết, lý do như sau :(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function sess_read($key) {
  global $user;
 
  // Write and Close handlers are called after destructing objects since PHP 5.0.5
  // Thus destructors can use sessions but session handler can't use objects.
  // So we are moving session closure before destructing objects.
  register_shutdown_function('session_write_close');
 
  // Handle the case of first time visitors and clients that don't store cookies (eg. web crawlers).
  if (!isset($_COOKIE[session_name()])) {
    $user = drupal_anonymous_user();
    return '';
  }
 
  // Otherwise, if the session is still active, we have a record of the client's session in the database.
  $user = db_fetch_object(db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = '%s'", $key));
 
  // We found the client's session record and they are an authenticated user
  if ($user && $user->uid > 0) {
    // This is done to unserialize the data member of $user
    $user = drupal_unpack($user);
 
    // Add roles element to $user
    $user->roles = array();
    $user->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user';
    $result = db_query("SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d", $user->uid);
    while ($role = db_fetch_object($result)) {
      $user->roles[$role->rid] = $role->name;
    }
  }
  // We didn't find the client's record (session has expired), or they are an anonymous user.
  else {
    $session = isset($user->session) ? $user->session : '';
    $user = drupal_anonymous_user($session);
  }
 
  return $user->session;
}

Tức là Drupal lưu session trong Database, nếu là authenticated user thì sẽ lưu trong DB với uid tương ứng, còn không thì sẽ lưu với uid=0. Do vô tình (không cẩn thận), tôi đã xóa mất thằng uid=0 đó nên session die là đương nhiên :p

Từ giờ chắc sẽ không còn mắc cái lỗi đó nữa ^^