2008/06/22

讓 Drupal 的 Node Import 模組支援 option widget

Node Import 模組是個非常好用的模組,可以把各種類型的 Node 資料先用打好,存成 csv 檔然後匯入。
不過對於自設的 CCK 欄位有個缺憾,就是在匯入之前必須先把 widget 的型態,由 option (select list / checkbox / radio) 改成 text,這樣才能匯入,實在是不太方便。
我修改了一點程式,讓它可以不用轉換 widget 的型態也能匯入,不過有個限制,目前修改的方式,只支援 Allowed values list 為下列形式:
value1
value2
vaule3

不支援 Allowed values list 為下列形式:
key1|value1
key2|value2
key3|value3

這是要注意的地方。

修改方式:
找出 node_import/supported/cck/content.inc 中的 function content_node_import_prepare
在該函數接近結尾的地方找到:

        // Unset the dummy column value.
        unset($node->$dummy_name);


改成:

        $option_type = array('options_select' => true, 'options_onoff' => true, 'options_buttons' => true);
        if (isset($option_type[$field['widget']['type']])) {
            $keys = array();
            foreach($node->$field_name as $value_list) {
               $keys[] = $value_list['value'];
            }
            if ($field['multiple'] || $field['widget']['type'] == 'options_onoff') {
               $node->$field_name += array('keys' => $keys);
            } else {
               $node->$field_name += array('key' => reset($keys));
            }
        }

        // Unset the dummy column value.
        unset($node->$dummy_name);


這樣就可以了~
報錯在這裡

2008/06/14

Drupal 的 Date 模組的一個小問題

目前首上有一個案子,要作一些統計的處理,其中有一向是關於日期欄位的。
我用 Drupal 的 Views 模組搭配 Date 模組來作,於 Argument 指定該日期欄位,這樣就可以顯示出我要的結果。
不過 Date 模組中有個小問題,那就是在生成 SQL 命令時,會產生錯誤,其錯誤的理由是,日期欄位的名稱被設定成 range ,而剛好在 MySQL 中 range 是保留字,必須用 `range` 才能使用該名稱。
所以我修改了 date_views.inc 中的 _date_views_argument_range_handler 函數

找到:
$fieldinfo['fieldname'] = 'range';

改成:
$fieldinfo['fieldname'] = '`range`';

這個問題於 Date 模組 V1 跟 V2 的版本都會發生,報錯在這裡

2008/06/03

擴充 DateTime 類別

今天在處理一個日期比較的問題,發現 DateTime 類別可以進行 1970/01/01 以前的日期比較,不過由於該類別建構式比較嚴格,所以我將他繼承後擴充改寫了一番。
程式碼在下面:

class Zyme_DateTime extends DateTime{
    function __construct($時間 = null, $時區 = null){
        if ($時間 instanceof DateTime) {
            $_時間 = $時間->format('c');
        } else if (is_int($時間)) {
            $_時間 = '@' . $時間;
        } else {
            $_時間 = (string)$時間;
        }
           
        if (is_null($時區)) {
            parent::__construct($_時間);
        } else {
            $_時區 = self::時區($時區);
            parent::__construct($_時間, $_時區);
            $this->setTimezone($_時區);
        }
    }
   
    function parse(){
        return date_parse($this->format('c'));
    }

    function 時戳(){
        return (int)$this->format('U');
    }
   
    function 凌晨(){
        $this->setTime(0,0,0);
        return $this;
    }

    function 午夜(){
        $this->setTime(23,59,59);
        return $this;
    }
   
    static function 時區($時區 = null){
        if ($時區 instanceof DateTimeZone) {
            return $時區;
        } else if (is_null($時區)) {
            $_時區 = date_default_timezone_get();
        } else if (is_numeric($時區)) {
            $_時區 = self::數字時區($時區);
        } else {
            $_時區 = self::字串時區($時區);
        }
        return new DateTimeZone($_時區);
    }

    static protected function 數字時區($時區){
        $_時區 = (Zyme_Filter::數字範圍($時區, -12, 12))
            ? (int)((float)$時區 * 3600)
            : (int)$時區;
        $_表格 = self::時區位移表格();
        $_輸出 = &$_表格[$_時區];
        return (isset($_輸出))
            ? $_輸出
            : 'UTC';
    }
   
    static protected function 字串時區($時區){
        $_表格 = self::時區識別表格();
        $_時區 = (string)$時區;
        return (isset($_表格[$_時區]))
            ? $_時區
            : 'UTC';
    }
   
    static function 時區識別表格(){
        static $_時區 = array();
        if (0 === count($_時區)) {
            $_時區 = array_flip(DateTimeZone::listIdentifiers());
        }
        return $_時區;
    }
         
    static function 時區位移表格(){
        static $_時區 = array();
        if (0 !== count($_時區)){
            return $_時區;
        }
        $_表格 = DateTimeZone::listAbbreviations();
        foreach ($_表格 as $_項目){
            foreach ($_項目 as $_內容) {
                if (false === isset($_時區[$_內容['offset']])) {
                    $_時區[$_內容['offset']] = $_內容['timezone_id'];
                }
            }
        }
        ksort($_時區);
        return $_時區;
    }   

}