Tommy 碎碎念

Tommy Wu's blog

« 上一篇 | 下一篇 »

Gallery 3 中文修正 part 2
post by tommy @ 15 十二月, 2011 17:22

之前提過 Gallery 3 內部是使用 utf-8 在處理 (實際上, 討論區與官網的文章似乎也多次提到要傳入參數時要用 utf-8 編碼的字串才可以), 不過... 另人不解的是, 為什麼一個說是用 utf-8 字串來處理資料的程式, 反而不能處理 utf-8 的中文路徑與檔名呢?

在不小心使用 pathinfo() 來取得檔名時, 發現只抓到英文的字元, 所有的中文字都不見了, 而 php 中對 pathinfo() 的解釋是這個函式會依據 setlocale() 而有不同的結果, 所以.... 看起來應該是 Gallery 之前有使用 setlocale(), 但設定了錯誤的參數吧.

試著在 local.php 中加上 setlocale(LC_ALL, "zh_TW.UTF-8"); 不過... 似乎沒有作用, 看來是先跑 local.php 之後才去另外做了這個設定.

找一下程式碼, 發現在 kohana 這個 framework 的 system/core/Kohana.php 有執行一次 setlocale(), 而且是設成 en_US.UTF-8, 應該也可以才對, 試著直接改成 zh_TW.UTF-8, 發現一樣不行, 所以應該在這之後還會執行一次.

接著在 modules/gallery/libraries/Gallery_I18n.php 發現有好幾次執行 setlocale() 的動作, 直接在這之後再做一次 setlocale(LC_ALL, "zh_TW.UTF-8"); 或 setlocale(LC_ALL, "en_US.UTF-8"); 之後, 果然在 Gallery 3 中就可以正確的處理 UTF-8 的路徑與檔案名稱了. 看起來, 雖然 Gallery 會試著傳入一堆 locale 的值去設定, 不過.... 它的第一個值並不包含字元集, 也就是當預設的 locale 是 zh_TW 時, 會變成去做 setlocale(LC_ALL, "zh_TW"); 結果, php 在嘗試第一個 locale 就會成功, 也就不會再去試後而的 zh_TW.UTF-8 了, 這時... 反而不能正確的處理 UTF-8 字元了.

修改的方法, 看是要直接把這段改掉, 直接去設定, 或把沒有指定字元集的那個放到陣列後頭, 都可以修正這個問題:

--- gallery3.orig/modules/gallery/libraries/Gallery_I18n.php  2011-05-25 12:04:04.000000000 +0800
+++ gallery3/modules/gallery/libraries/Gallery_I18n.php 2011-12-14 16:12:26.500087463 +0800
@@ -77,7 +77,11 @@
list ($php_locale, $unused) = explode('.', $php_locale . '.');
if ($php_locale != $locale) {
// Attempt to set PHP's locale as well (for number formatting, collation, etc.)
- $locale_prefs = array($locale);
+ // twu2 begin
+ // move the locale without CHARSET to latest... we prefer to use UTF-8
+ //$locale_prefs = array($locale);
+ $locale_prefs = array();
+ // twu2 end
// Try appending some character set names; some systems (like FreeBSD) need this.
// Some systems require a format with hyphen (eg. Gentoo) and others without (eg. FreeBSD).
$charsets = array('utf8', 'UTF-8', 'UTF8', 'ISO8859-1', 'ISO-8859-1');
@@ -89,8 +93,14 @@
foreach ($charsets as $charset) {
$locale_prefs[] = $locale . '.' . $charset;
}
+ // twu2 begin
+ // try the one without CHARSET only all CHARSET failed
+ $locale_prefs[] = $locale;
+ // twu2 end
$locale_prefs[] = 'en_US';
$php_locale = setlocale(LC_ALL, $locale_prefs);
+ //$php_locale = setlocale(LC_ALL, 'zh_TW.UTF-8');
+ //$php_locale = setlocale(LC_ALL, 'en_US.UTF-8');
}
if (is_string($php_locale) && substr($php_locale, 0, 2) == 'tr') {
// Make PHP 5 work with Turkish (the localization results are mixed though).

經過這個修改後, 使用中文的路徑與檔名就不會有問題了.

不過接下去與之前的 part 1 相同, 那幾個地方一樣要更改, 只是並不用去針對 name 也做更改, 只要更改 slug (這個完全不接受非英文字元, 看不出有何用意) 的部份就可以.

首先是相簿的部份:

--- gallery3.orig/modules/gallery/controllers/albums.php  2011-05-25 12:04:04.000000000 +0800
+++ gallery3/modules/gallery/controllers/albums.php 2011-12-14 19:30:12.914153944 +0800
@@ -90,10 +90,29 @@
$album->type = "album";
$album->parent_id = $parent_id;
$album->name = $form->add_album->inputs["name"]->value;
+ // twu2 begin
+ // avoid non-english name
+/*
+ // we don't need this any more, if we can have correct setlocale() with utf-8 charset
+ $album->name = item::convert_filename_to_slug($album->name);
+ if ($album->name == '')
+ $album->name = 'album'.strftime("%Y%m%d%H%M%S").'-'.rand();
+*/
+ // twu2 end
$album->title = $form->add_album->title->value ?
$form->add_album->title->value : $form->add_album->inputs["name"]->value;
$album->description = $form->add_album->description->value;
$album->slug = $form->add_album->slug->value;
+ // twu2 begin
+ // also copy from name if slug is empty
+ $album->slug = item::convert_filename_to_slug($album->slug);
+ if ($album->slug == '')
+ $album->slug = item::convert_filename_to_slug($album->name);
+ if ($album->slug == '')
+ $album->slug = 'album'.strftime("%Y%m%d%H%M%S").'-'.rand();
+ // convert for title
+ $album->title = item::convert_filename_to_title($album->title);
+ // twu2 end
$album->validate();
} catch (ORM_Validation_Exception $e) {
// Translate ORM validation errors into form error messages

接著是 REST 的部份:

--- gallery3.orig/modules/gallery/helpers/item_rest.php  2011-05-25 12:04:04.000000000 +0800
+++ gallery3/modules/gallery/helpers/item_rest.php 2011-12-14 16:23:05.504784462 +0800
@@ -159,9 +159,24 @@
$item->type = "album";
$item->parent_id = $parent->id;
$item->name = $entity->name;
+ // twu2 begin
+ // avoid non-english name
+ //$item->name = item::convert_filename_to_slug($item->name);
+ if ($item->name == '')
+ $item->name = 'album'.strftime("%Y%m%d%H%M%S").'-'.rand();
+ // twu2 end
$item->title = isset($entity->title) ? $entity->title : $entity->name;
$item->description = isset($entity->description) ? $entity->description : null;
$item->slug = isset($entity->slug) ? $entity->slug : null;
+ // twu2 begin
+ // copy from name if empty
+ $item->slug = item::convert_filename_to_slug($item->slug);
+ if ($item->slug == '')
+ $item->slug = item::convert_filename_to_slug($item->name);
+ if ($item->slug == '')
+ $item->slug = item::convert_filename_to_slug(base64_encode($item->name));
+ $item->title = item::convert_filename_to_title($item->title);
+ // twu2 end
$item->save();
break;
 
@@ -175,9 +190,37 @@
$item->parent_id = $parent->id;
$item->set_data_file($request->file);
$item->name = $entity->name;
+ // twu2 begin
+ // avoid non-english name
+ $name = $item->name;
+ $ext = '';
+ $pos = strrpos($item->name, '.');
+ if ($pos !== false) {
+ $ext = substr($item->name, $pos);
+ $name = substr($item->name, 0, $pos);
+ }
+ //$item->name = item::convert_filename_to_slug($name);
+ $item->name = $name;
+ if ($item->name == '') {
+ if ($item->type == 'photo')
+ $item->name = 'photo'.strftime("%Y%m%d%H%M%S").'-'.rand();
+ else
+ $item->name = 'movie'.strftime("%Y%m%d%H%M%S").'-'.rand();
+ }
+ $item->name .= $ext;
+ // twu2 end
$item->title = isset($entity->title) ? $entity->title : $entity->name;
$item->description = isset($entity->description) ? $entity->description : null;
$item->slug = isset($entity->slug) ? $entity->slug : null;
+ // twu2 begin
+ // copy from name if empty
+ $item->slug = item::convert_filename_to_slug($item->slug);
+ if ($item->slug == '')
+ $item->slug = item::convert_filename_to_slug($item->name);
+ if ($item->slug == '')
+ $item->slug = item::convert_filename_to_slug(base64_encode($item->name));
+ $item->title = item::convert_filename_to_title($item->title);
+ // twu2 end
$item->save();
break;

最後是 Gallery Remote 的部份:

--- gallery3.orig/modules/remote/controllers/gallery_remote.php  2011-06-29 15:47:43.000000000 +0800
+++ gallery3/modules/remote/controllers/gallery_remote.php 2011-12-15 16:12:29.422343598 +0800
@@ -181,6 +181,14 @@
$name = trim($input->post('newAlbumName'));
$title = trim($input->post('newAlbumTitle'));
$desc = trim($input->post('newAlbumDesc'));
+ // twu2 begin
+ // GR will strip all non-ascii char for name?
+ $xtitle = preg_replace('/[\x80-\xffffff]/', '', $title);
+ // for empty name or name = strip of title, we copy it from title again
+ if ($name == '' || $name == $xtitle)
+ $name = $title;
+ if ($name == '') $name = 'album'.strftime('%Y%m%d%H%M%S').'-'.rand();
+ // twu2 end
 
if($album=='0') $parent = item::root();
else $parent = ORM::factory("item")->where("slug", "=", $album)->find();
@@ -192,20 +200,30 @@
 
$album->name = $name;
$album->slug = item::convert_filename_to_slug($name); // <= verification fails if this property has not been set!!!
+ // twu2 begin
+ // if slug is empty (after convert name, might be empty), use base64
+ if ($album->slug == '')
+ $album->slug = item::convert_filename_to_slug(base64_encode($name)); // <= verification fails if this property has not been set!!!
+ $title = item::convert_filename_to_title($title);
+ // twu2 end
$album->title = $title;
$album->title or $album->title = $album->name;
$album->description = $desc;
$album->view_count = 0;
$album->sort_column = 'weight';
$album->sort_order = 'ASC';
-
try {
$album->validate();
 
try {
$album->save();
 
- $reply->set('album_name', $album->name);
+ // twu2 begin
+ // return slug instead of name
+ // because name might include non-english char, it will make GR fail
+ //$reply->set('album_name', $album->name);
+ $reply->set('album_name', $album->slug);
+ // twu2 end
$reply->set('status_text', 'New album created successfuly.');
$reply->send();
 
@@ -274,7 +292,29 @@
else if($userfilename!='') $filename = $userfilename;
else $filename = $_FILES['userfile']['name'];
 
- $slug = $filename;
+ // twu2 begin
+ // GR will change the non-english char to '?'? so we get it from title
+ // fix for non-english name?
+ if (strchr($filename, '?') !== false) {
+ // non english name?
+ // the pathinfo() might not work setlocale() for non utf-8 locale...
+ // so we use strrpos to find filename and extension
+ $name = $title;
+ $ext = '';
+ $pos = strrpos($title, '.');
+ if ($pos !== false) {
+ $ext = substr($title, $pos);
+ $name = substr($title, 0, $pos);
+ }
+ if ($name === '') {
+ $name = 'photo'.strftime("%Y%m%d%H%M%S").'-'.rand();
+ }
+ $filename = $name.$ext;
+ }
+ $slug = item::convert_filename_to_slug($filename);
+ if ($slug == '') $slug = item::convert_filename_to_slug(base64_encode($filename));
+ // $slug = $filename;
+ // twu2 end
$pos = strpos($slug, '.');
if($pos!==false)
$slug = substr($slug, 0, $pos);
@@ -285,7 +325,11 @@
$item->parent_id = $parent->id;
$item->set_data_file($_FILES['userfile']['tmp_name']);
$item->name = $filename;
- $item->slug = item::convert_filename_to_slug($slug);
+ // twu2 begin
+ // we already convert it
+ $item->slug = $slug;
+ //$item->slug = item::convert_filename_to_slug($slug);
+ // twu2 end
$item->mime_type = $type;
$item->title = $title;
$item->title or $item->title = ' '; //don't use $item->name as this clutters up the UI

經過這樣的處理, 應該就能正確的使用中文名稱了.

另外, 建議改用 REST 的 client 來連線, 因為 Gallery Remote 在我測試的時候, 有時候對中文處理會有問題, 不過有時候又正常... 還看不出來是為什麼.

Del.icio.us Furl HEMiDEMi Technorati MyShare
commons icon [1] Re:Gallery 3 中文修正 part 2 [ 回覆 ]

請問Tommy:
我在安裝時,一直出現要建 var 目錄,可是 var 明明已經在 gallery3/ 下面建好,也開777了,安裝時還是報 var 不在?

謝謝

commons icon [2] Re:Gallery 3 中文修正 part 2 [ 回覆 ]

請問tommy:

弄了很久,中文相簿是可以
但是檔案名稱若是中文,則無法顯示圖檔
有關檔案名稱的處理,請問您知道要改哪些檔案嗎?
或是可否提示個方向

謝謝

commons icon [3] Re:Gallery 3 中文修正 part 2 [ 回覆 ]

中文檔名這一篇不就有提到了?
還是指匯入後放在 server 上的檔案還要保持中文檔名? 如果是這個, 就沒辦法.

迴響
暱稱:
標題:
個人網頁:
電子郵件:
authimage

迴響

  

Bad Behavior 已經阻擋了 67 個過去 7 天試圖闖關的垃圾迴響與引用。
Power by LifeType. Template design by JamesHuang. Valid XHTML and CSS