<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 14,  comments - 37,  trackbacks - 0

    DotProject是一個(gè)基于AMP(apache+mysql+php)的開源項(xiàng)目管理工具,DotProject可以支持多語(yǔ)言并采用模塊化設(shè)計(jì)以便于擴(kuò)展。
    最近需要一個(gè)項(xiàng)目管理軟件,于是就下載DotProject進(jìn)行了試用,感覺(jué)不錯(cuò),但有中文有亂碼問(wèn)題,如:日歷和gantt圖。現(xiàn)就對(duì)解決DotProject亂碼進(jìn)行一下總結(jié),由于本人以前沒(méi)接觸過(guò)PHP,初次修改有錯(cuò)的地方請(qǐng)大家指正。
     機(jī)器環(huán)境:WindowsXP SP2簡(jiǎn)體中文,apache2.0.59, mysql-5.0.16-win32, php-5.2.0,其他版本沒(méi)有測(cè)過(guò),不能保證在其他版本下正確運(yùn)行,由其在PHP4下。
    1. 加入語(yǔ)言包
     DotProject有比較不錯(cuò)的多語(yǔ)言包,項(xiàng)目叫dot modules,在sourceforge上有。DotProject的語(yǔ)言包目錄./locales,運(yùn)行可根據(jù)配置動(dòng)態(tài)加載語(yǔ)言包進(jìn)行對(duì)照轉(zhuǎn)換相應(yīng)的語(yǔ)言。下載中文語(yǔ)言包解壓后并復(fù)制到語(yǔ)言目錄locales下,修改語(yǔ)言包文件夾下locales.php文件:
    $locale_char_set = 'GB2312';為$locale_char_set = 'utf-8';
    同時(shí)把英文語(yǔ)言包的同名文件也進(jìn)行修改。使用'utf-8'的好處就是瀏覽器用unicode(utf-8)解碼,頁(yè)面可顯示多種語(yǔ)言文字。防照英文語(yǔ)言包創(chuàng)建lang.php文件,加入如下內(nèi)容:

    <?php
    $dir = basename(dirname(__FILE__));
    $LANGUAGES['zh-cn'= array ( $dir, 'Chinese (Simplified)', '簡(jiǎn)體中文', 'chs');
    ?>


    如果繁體則:

    <?php
    $dir = basename(dirname(__FILE__));
    $LANGUAGES['zh-tw'= array ( $dir, 'Chinese (Traditional)', '繁體中文', 'cht');
    ?>

    同時(shí)把目錄下的所有對(duì)照文件轉(zhuǎn)換為utf-8編碼存儲(chǔ)(可用ultraEdit等文本編輯器轉(zhuǎn)換或登錄后用DotProject翻譯管理進(jìn)行更改),初步漢化完成。
    2. 修正在中文下日歷的亂碼問(wèn)題
    本地化語(yǔ)言后日歷的星期顯示為亂碼,這是由于DotProject采用讀取操作系統(tǒng)本地語(yǔ)言區(qū)域日期格式引起的,在windowsXP中文版默認(rèn)是“星期幾,xxxx-x-x”,且可能為GB2312編碼(本地區(qū)域語(yǔ)言可以更改)。DotProject讀取操作系統(tǒng)的日期用utf8_encode轉(zhuǎn)換后再顯示,這樣只要操作系統(tǒng)的本地區(qū)域日期語(yǔ)言格式和運(yùn)行DotProject選取的語(yǔ)言不一至?xí)r就會(huì)出現(xiàn)亂碼,顯然不是聰明的做法。
    1)語(yǔ)言包文件夾下locales.php文件中加入日期格式對(duì)照表變量如下:

    $locale_weeks = array('星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六');
    $locale_short_week = array('', '', '', '', '', '', '');
    $locale_months = array(null, '一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月');
    $locale_short_months = array(null, '1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月');

    2)DotProject的日期處理基類在lib\PEAR\Date下Calc.php文件中,修改或增加其中的相關(guān)幾個(gè)函數(shù)。
    加入和修改如下函數(shù):

    //***************************************************************
    //得到月全名稱列表

    function getMonthNames()
    {
        
    global $locale_months;
      
    if(!empty($locale_months)){
        
    $months = $locale_months;
     
     }
    else{
        
    for($i=1;$i<13;$i++){
            
    $months[$i= strftime('%B', mktime(0, 0, 0, $i, 1, 2001));
        }
      }
      
    return($months);
    }

    //****************************************************************
    //得到月短名稱列表    

    function getMonthShortNames($length=3)
    {
            
    global $locale_short_months;
       
    if(!empty($locale_short_months)){
        
    $months = $locale_short_months;
       
      }
    else{
                
    for($i=1;$i<13;$i++){
                    
    $months[$i= strftime('%B', mktime(0, 0, 0, $i, 1, 2001));
                    
    $months[$i= substr($months[$i], 0, $length);
                }
            }
            
    return($months);
    }  

    //*****************************************************************
    //得到星期全名稱列表     

    function getWeekDays()
    {
            
    global $locale_weeks;
       
    if(!empty($locale_weeks)){
        
    $weekdays = $locale_weeks;
      
      }
    else{
          
    for($i=0;$i<7;$i++){
                
    $weekdays[$i= strftime('%A', mktime(0, 0, 0, 1, $i, 2001));
                }
            }        
            
    return($weekdays);
    }

    //****************************************************************
    //得到星期短名稱列表   

    function getShortWeekDays($length=3)
    {
            
    global $locale_short_week;
       
    if(!empty($locale_short_week)){
        
    $weekdays = $locale_short_week;
        
      }
    else{
                
    for($i=0;$i<7;$i++){
                    
    $weekdays[$i= strftime('%A', mktime(0, 0, 0, 1, $i, 2001));
                    
    $weekdays[$i= substr($weekdays[$i],0,$length);                
                }
            } 
            
    return($weekdays);


    //****************************************************************
    //得到月全名稱

    function getMonthFromFullName($month)
    {
            
    $month = strtolower($month);
            
    $months = Date_Calc::getMonthNames();
            
    while(list($id, $name= each($months)){
                
    if(ereg($month, strtolower($name))){
                    
    return($id);
                }
            }
            
    return(0);
    }  

    //****************************************************************
    //得到月短名稱 

    function getMonthAbbrname($month,$length=3)
    {
            
    $month = strtolower($month);
            
    $months = Date_Calc::getMonthShortNames();
            
    while(list($id, $name= each($months)){
                
    if(ereg($month, strtolower($name))){
                    
    return($id);
                }
            }
            
    return(0);
    // end func getMonthAbbrname

    //****************************************************************
    //得到星期短名稱

    function getWeekdayFullname($day="",$month="",$year="")
    {
            
    if(empty($year))
                
    $year = Date_Calc::dateNow("%Y");
            
    if(empty($month))
                
    $month = Date_Calc::dateNow("%m");
            
    if(empty($day))
                
    $day = Date_Calc::dateNow("%d");

            
    $weekday_names = Date_Calc::getWeekDays();
            
    $weekday = Date_Calc::dayOfWeek($day,$month,$year);

            
    return $weekday_names[$weekday];

    // end func getWeekdayFullname

    //****************************************************************
    //得到星期短名稱

    function getWeekdayAbbrname($day="",$month="",$year="",$length=3)
    {
            
    if(empty($year))
                
    $year = Date_Calc::dateNow("%Y");
            
    if(empty($month))
                
    $month = Date_Calc::dateNow("%m");
            
    if(empty($day))
                
    $day = Date_Calc::dateNow("%d");

            
    $weekday_names = Date_Calc::getShortWeekDays();
            
    $weekday = Date_Calc::dayOfWeek($day,$month,$year);

            
    return $weekday_names[$weekday];        
            
    // end func getWeekdayAbbrname

    以上幾個(gè)函數(shù)有的是修改的,有的是新加的,由于較多,不再一一詳細(xì)說(shuō)明。思路是明顯的,就是通過(guò)對(duì)日期列表的的映射獲得相應(yīng)語(yǔ)言名稱。有興趣的朋友可能進(jìn)行補(bǔ)充和更正。
    3)修改日期顯示的亂碼處,在modules\calendar\calendar.class.php文件把function _drawDays()函數(shù)中

       foreach$wk as $day ) {
       
    $s .= " <th width="14%">" . htmlentities(utf8_encode($day), ENT_COMPAT, $locale_char_set. "</th>";
     }

     utf8_encode函數(shù)去掉修改為

     foreach$wk as $day ) {
       
    $s .= " <th width="14%">" . htmlentities($day, ENT_COMPAT, $locale_char_set. "</th>";
     }

    完整的函數(shù)如下:

    //***************************************************************
    function _drawDays() {
      
    global $locale_char_set;

      
    $bow = Date_Calc::beginOfWeek( null,null,null,null,LOCALE_FIRST_DAY );
      
    $y = substr$bow, 0, 4 );
      
    $m = substr$bow, 4, 2 );
      
    $d = substr$bow, 6, 2 );
      
    $wk = Date_Calc::getCalendarWeek( $d, $m, $y, "%a", LOCALE_FIRST_DAY );

      
    $s = $this->showWeek ? " <th>&nbsp;</th>" : "";
      
    foreach$wk as $day ) {
       
    $s .= " <th width="14%">" . htmlentities($day, ENT_COMPAT, $locale_char_set. "</th>";
      }

      
    return " <tr>$s </tr>";
    }
    //****************************************************************

    修改文件module/tasks/ae_dates.php 

    function cal_work_day_conv($val) {
     
    GLOBAL $locale_char_set;
     
    $wk = Date_Calc::getCalendarWeek( null, null, null, "%a", LOCALE_FIRST_DAY );
     
     
    $day_name = $wk[($val - LOCALE_FIRST_DAY)%7];
     
     
    //把utf8_encode調(diào)用處注釋,不進(jìn)行編碼轉(zhuǎn)換
    /*

     if ($locale_char_set == "utf-8" && function_exists("utf8_encode")) {
         $day_name = utf8_encode($day_name);
     }
    */ 
     
    return htmlentities($day_name, ENT_COMPAT, $locale_char_set);

    }

    以上是把顯示日期名稱時(shí)的utf8_encode轉(zhuǎn)碼去掉,因?yàn)樽x到的日期名稱本來(lái)就是utf-8編碼,類似的地方可能還有,如果找到都要去掉。

    3. 修正在中文下Gantt圖的亂碼問(wèn)題
    DotProject的圖形模塊使用了jpgraph。JpGraph是PHP專門進(jìn)行繪制圖表的類庫(kù)。它使得作圖變成了一件非常簡(jiǎn)單的事情,你只需從數(shù)據(jù)庫(kù)中取出相關(guān)數(shù)據(jù),定義標(biāo)題,圖表類型,然后的事情就交給JpGraph,只需掌握為數(shù)不多的JpGraph內(nèi)置函數(shù)(可以參照J(rèn)pGraph附帶例子學(xué)習(xí)),就可以畫出非常炫目的圖表!
    JpGraph要求PHP版本為4.04以上,并且支持GD庫(kù)且GD庫(kù)的版本應(yīng)為2.0,而不是1.0。JpGraph有PHP4和PHP5兩種版本(由于我的環(huán)境是PHP5,所以下載了最新PHP5版本,在附件中修改過(guò)的DotProject包含這個(gè)版本,請(qǐng)使用PHP4更換相應(yīng)的版本)。
    Gantt圖的亂碼問(wèn)題的在于jpgraph中沒(méi)有對(duì)中文及其他語(yǔ)言文字處理好。
    1)修改jpgraph配置文件
    新建字體文件夾和修改lib/jpgraph/src/jpg-config.inc.php文件,在lib/jpgraph路徑新建fonts文件夾,把所要的字庫(kù)復(fù)制到該文件夾下。
    在文件lib/jpgraph/src/jpg-config.inc.php中加入如下語(yǔ)句(或把相應(yīng)的注釋去掉后修改) 

    DEFINE('TTF_DIR','./lib/jpgraph/fonts/'); //設(shè)置jpgraphTTF(字體)文件夾
    DEFINE('SIMSUN_TTF_FONT','simsun.ttc');//使用'simsun.ttc'(windows下的宋體)
    DEFINE('CHINESE_TTF_FONT','simsun.ttc');

     2)修改文件module/tasks/gantt.php和module/projects/gantt.php
    新版在繪制Gantt圖時(shí)報(bào)錯(cuò):You are trying to use the locale (%s) which your PHP installation does not support. Hint: Use ‘ ’ to indicate the default locale for this geographic region.
    這是由于jpgraph沒(méi)有加入選定的日期格式如'chs',可修改SetDateLocale處如下:

    $jpLocale = dPgetConfig( 'jpLocale' );
    if ($jpLocale) {
     
    $graph->scale->SetDateLocale( $jpLocale );
    }
    else {
        
    $graph->scale->SetDateLocale( $AppUI->user_lang[0] );//第一個(gè)估計(jì)會(huì)有或注釋掉和設(shè)為 ‘ ’

    }

    Gantt圖繪制分兩部分,一部分是由DotProject生成的項(xiàng)目管理的標(biāo)題等,一部分是用戶業(yè)務(wù)產(chǎn)生的內(nèi)容區(qū)部分如項(xiàng)目和任務(wù)名稱。對(duì)于第一部分繪制字體編碼保持和DotProject一致。
    在語(yǔ)言包文件夾下locales.php文件中加入如下定義(本例是簡(jiǎn)體中文)
    $LOCALE_FONT=30;
    30是在jpgraph中定義的語(yǔ)言字體標(biāo)識(shí)(如中文為DEFINE("FF_SIMSUN",30);),詳見(jiàn)jpgraph.php文件。 這樣在繪制標(biāo)題部分取FF_SIMSUN索引的字體。
    在文件module/tasks/gantt.php和module/projects/gantt.php中定義當(dāng)前標(biāo)題要使用的字體,加入如下語(yǔ)句:

    if (!empty($LOCALE_FONT)){
        
    define("CRURRENT_FONT",$LOCALE_FONT);
    }
    else {
        
    define("CRURRENT_FONT",FF_ARIAL);
    }

    這樣在設(shè)定字體的地方設(shè)定CRURRENT_FONT就可以了。把
    //$graph->scale->actinfo->SetFont(FF_ARIAL);改為
    $graph->scale->actinfo->SetFont(CRURRENT_FONT, FS_NORMAL, 10);//標(biāo)題信息
    找到
    if (is_file( TTF_DIR."arialbd.ttf" ))
     $graph->scale->tableTitle->SetFont(FF_ARIAL,FS_BOLD,12); 改為
    $graph->scale->tableTitle->SetFont(CRURRENT_FONT, FS_NORMAL, 11);//標(biāo)題頭
    在最后
    $vline = new GanttVLine($today, $AppUI->_('Today', UI_OUTPUT_RAW));語(yǔ)句后插入如下語(yǔ)句:
    $vline->title->SetFont(CRURRENT_FONT, FS_NORMAL, 10);//顯示today(今天)
    這樣繪制標(biāo)題部分就修改完畢。
    第二部分內(nèi)容區(qū)則要根據(jù)要繪制的文字編碼動(dòng)態(tài)設(shè)定字體。因此在module/tasks/gantt.php和module/projects/gantt.php文件中加入判斷字符在什么語(yǔ)言區(qū)返回相應(yīng)的字體(根據(jù)utf-8)本例只實(shí)現(xiàn)中文區(qū),可以有不對(duì)地方,望大家指正。

    //utf-8 region segment 一-?
    function GetutfTTF($str

      
    if (preg_match("/^([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){1}/",$word== true || preg_match("/([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){1}$/",$word== true || preg_match("/([".chr(228)."-".chr(233)."]{1}[".chr(128)."-".chr(191)."]{1}[".chr(128)."-".chr(191)."]{1}){2,}/",$str== true)
      {
         
    return (FF_CHINESE); //返回中文字體標(biāo)識(shí)FF_CHINESE
      }
         
    return (FF_ARIAL); //返回默認(rèn)字體標(biāo)識(shí)FF_ARIAL
    }

    然后在畫gantt圖相應(yīng)的項(xiàng)目和任務(wù)要顯示的名稱判斷是否在中文,設(shè)置對(duì)應(yīng)的字體,如:
    $bar->title->SetFont(GetutfTTF($name), FS_NORMAL, 10);
    $bar2->title->SetFont(GetutfTTF($t["task_name"]), FS_NORMAL, 10);

    所有$bar繪制都屬于內(nèi)容區(qū),都把相應(yīng)部分用如上方法設(shè)定字體。繪制Gantt圖部分就修改完畢,看看效果:
    英文:
     


    中文: 

    4. 其他補(bǔ)充說(shuō)明
    以上所有的編碼都設(shè)定為utf-8,因此建議把數(shù)據(jù)庫(kù)的服務(wù)器端和客戶端字符集都改為utf-8。Mysql修改配置文件my.cnf或my.ini即可。
    如phpmyadmin瀏覽DotProject的mysql數(shù)據(jù)庫(kù),設(shè)定為”中文-Chinese Simplified(utf-8)”,如果發(fā)現(xiàn)在亂碼,請(qǐng)?jiān)趇ncludes/db_adodb.php文件中function db_connect()函數(shù)加上
     $db->Query("Set Names 'utf8'");
    這樣字符編碼就和phpmyadmin保持一致,用phpmyadmin瀏覽數(shù)據(jù)就沒(méi)有亂碼了。

    后話:
    本文雖然是解決亂碼問(wèn)題,其中包含軟件國(guó)際化思想。在軟件支持多語(yǔ)言文字時(shí),可以分為兩部分,一部分軟件本身通過(guò)配置有多種語(yǔ)言版本,一部分就是支持不同語(yǔ)言文字的處理。就象瀏覽器,雖然各種語(yǔ)言版本,但可以正常瀏覽不同語(yǔ)言的網(wǎng)頁(yè)。這主要是由于采用了統(tǒng)一編碼utf8-unicode(大多采用此種編碼)。可以預(yù)見(jiàn),不久亂碼問(wèn)題由于都采用統(tǒng)一編碼將不復(fù)存在。軟件的多語(yǔ)言只是軟件國(guó)際化第一步,中國(guó)軟件業(yè)國(guó)際化任重道遠(yuǎn)。
    在附件中是由DotProject2.1rc版修改過(guò)的壓縮文件,并加入了最新的JpGraph for PHP5版本。有興趣的朋友可以下載大家共同研究。(由于不能上傳附件,需要的朋友可以留下email地址)

    下載地載:http://bbs.php168.com/read.php?tid=136083

    posted on 2007-07-19 15:10 冰封的愛(ài) 閱讀(851) 評(píng)論(0)  編輯  收藏 所屬分類: 開源項(xiàng)目

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(3)

    隨筆檔案

    文章分類

    文章檔案

    相冊(cè)

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲小说图片视频| 亚洲中文字幕无码永久在线| 久久久久久久亚洲Av无码| 久久久WWW免费人成精品| 亚洲国产一级在线观看| 国产精品亚洲专区一区| 国产在线观看www鲁啊鲁免费| 亚洲爆乳大丰满无码专区| 永久免费看bbb| 阿v视频免费在线观看| 亚洲av无码专区在线观看素人| 日韩亚洲人成在线综合| 亚洲国产精品狼友中文久久久| 人禽伦免费交视频播放| 国产亚洲精品a在线无码| 免费91最新地址永久入口 | 51在线视频免费观看视频| 亚洲人成亚洲精品| 麻豆视频免费播放| 亚洲日产乱码一二三区别| 国产精品嫩草影院免费| 精品一区二区三区免费视频| 国产v亚洲v天堂无码网站| 亚洲网站在线免费观看| 在线精品亚洲一区二区| 免费在线一级毛片| 免费av一区二区三区| 亚洲一区动漫卡通在线播放| 日韩免费一区二区三区| 久久嫩草影院免费看夜色| 77777_亚洲午夜久久多人| 四虎成人免费观看在线网址 | 亚洲风情亚Aⅴ在线发布| 浮力影院亚洲国产第一页| 久操视频在线免费观看| 亚洲乱码在线观看| 一本久久a久久精品亚洲| 国产日本一线在线观看免费| 青娱乐在线视频免费观看| 老司机亚洲精品影院无码| 国产成人免费A在线视频|