dede的聯動類型是是通過將字段和系統枚舉表dede_sys_enum相關聯的,獨立模型的表中聯動類別字段存儲的是表dede_sys_enum的枚舉值,這是一個數值,類似于代號的意思,當要顯示獨立模型的聯動類別字段時,首先根據這個枚舉值在dede_sys_enum中找出相應枚舉名,然后才顯示出來。在模版文件中我們不需要知道這個過程是如何進行的,只需按照顯示一般字段的方式就能正確顯示聯動類型了。
這篇文章主要討論的就是在dede代碼中是如何顯示聯動類型字段的。
不管是在文章頁面還是列表頁面都能直接使用[field:codecategory/]這樣的方式來顯示聯動類型,這里就以列表頁面為例。
顯示獨立模型的列表是通過/include/arc.sglistview.class.php來完成的,在arc.sglistview.class.php的GetArcList方法中如下代碼完成了對獨立模型所有字段的特殊處理:
| foreach($this->ChannelUnit->ChannelFields as $k=>$arr){if(isset($row[$k])){$row[$k] = $this->ChannelUnit->MakeField($k,$row[$k]);}} | 
沒有這段代碼獨立模型的聯動字段就顯示的是亂七八糟的數字。ChannelUnit的MakeField的在/include/channelunit.class.php中,用于處理某個字段的值,代碼如下:
| /*** 處理某個字段的值** @access public* @param string $fname 字段名稱* @param string $fvalue 字段值* @param string $addvalue 增加值* @return string*/function MakeField($fname, $fvalue, $addvalue=''){//處理各種數據類型$ftype = $this->ChannelFields[$fname]['type'];if($fvalue==''){if($ftype != 'checkbox') $fvalue = $this->ChannelFields[$fname]['default'];}if($ftype=='text'){$fvalue = HtmlReplace($fvalue);}else if($ftype=='textdata'){if(!is_file($GLOBALS['cfg_basedir'].$fvalue)){return '';}$fp = fopen($GLOBALS['cfg_basedir'].$fvalue,'r');$fvalue = '';while(!feof($fp)){$fvalue .= fgets($fp,1024);}fclose($fp);}else if($ftype=='addon'){$foldvalue = $fvalue;$tmptext = GetSysTemplets("channel_addon.htm");$fvalue = str_replace('~link~',$foldvalue,$tmptext);$fvalue = str_replace('~phpurl~',$GLOBALS['cfg_phpurl'],$fvalue);}else if(file_exists(DEDEINC.'/taglib/channel/'.$ftype.'.lib.php')){ echo "$fname-";echo "$fvalue $ftype<br>";include_once(DEDEINC.'/taglib/channel/'.$ftype.'.lib.php');$func = 'ch_'.$ftype;echo "$func";$fvalue = $func($fvalue,$addvalue,$this,$fname);}return $fvalue;} | 
其中,上面的不同case值處理不同字段類型,聯動類型在最后一個case中,他引入了/include/taglib/channel/stepselect.lib.php文件(因為聯動類型的$ftype值為stepselect),然后最終的代碼進入stepselect.lib.php的ch_stepselect方法中。
| <?phpif(!defined('DEDEINC')) exit("Request Error!");function ch_stepselect($fvalue,&$arcTag,&$refObj,$fname=''){return GetEnumsValue2($fname,$fvalue);}/*** 獲取二級枚舉的值** @version $Id: stepselect.lib.php 16:24 2010年7月26日Z tianya $* @package DedeCMS.Taglib* @copyright Copyright (c) 2007 - 2010, DesDev, Inc.* @license http://help.dedecms.com/usersguide/license.html* @link http://www.dedecms.com*/function GetEnumsValue2($egroup,$evalue=0){if( !isset($GLOBALS['em_'.$egroup.'s']) ){$cachefile = DEDEDATA.'/enums/'.$egroup.'.php';if(!file_exists($cachefile)){require_once(DEDEINC.'/enums.func.php');WriteEnumsCache();}if(!file_exists($cachefile)){return '';}else{require_once($cachefile);}}if($evalue>=500){if($evalue % 500 == 0){return (isset($GLOBALS['em_'.$egroup.'s'][$evalue]) ? $GLOBALS['em_'.$egroup.'s'][$evalue] : '');}else if (preg_match("#([0-9]{1,})/.([0-9]{1,})#", $evalue, $matchs)){$esonvalue = $matchs[1];$etopvalue = $esonvalue - ($esonvalue % 500);$esecvalue = $evalue;$GLOBALS['em_'.$egroup.'s'][$etopvalue] = empty($GLOBALS['em_'.$egroup.'s'][$etopvalue])? '': $GLOBALS['em_'.$egroup.'s'][$etopvalue];$GLOBALS['em_'.$egroup.'s'][$esonvalue] = empty($GLOBALS['em_'.$egroup.'s'][$esonvalue])? '': $GLOBALS['em_'.$egroup.'s'][$esonvalue];$GLOBALS['em_'.$egroup.'s'][$esecvalue] = empty($GLOBALS['em_'.$egroup.'s'][$esecvalue])? '': $GLOBALS['em_'.$egroup.'s'][$esecvalue];return $GLOBALS['em_'.$egroup.'s'][$etopvalue].' -- '.$GLOBALS['em_'.$egroup.'s'][$esonvalue].' -- '.$GLOBALS['em_'.$egroup.'s'][$esecvalue];}else{$elimit = $evalue % 500;$erevalue = $evalue - $elimit;$GLOBALS['em_'.$egroup.'s'][$erevalue] = empty($GLOBALS['em_'.$egroup.'s'][$erevalue])? '': $GLOBALS['em_'.$egroup.'s'][$erevalue];$GLOBALS['em_'.$egroup.'s'][$evalue] = empty($GLOBALS['em_'.$egroup.'s'][$evalue])? '': $GLOBALS['em_'.$egroup.'s'][$evalue];return $GLOBALS['em_'.$egroup.'s'][$erevalue].' -- '.$GLOBALS['em_'.$egroup.'s'][$evalue];}}} | 
其實我并沒有去研究ch_stepselect方法以及其調用的GetEnumsValue2方法,因為這里的關鍵是arc.sglistview.class.php的GetArcList方法中的那段代碼。
新聞熱點
疑難解答