從原理上教你如何刪除織夢dedecms自定義欄位
由於dedecms後臺沒有提供刪除自定義欄位的方法,我們只能自己手動操作刪除,下面的內容是刪除的方法和原理。
一、增加一個自定義欄位,用於下面的示例中講解刪除。
“核心-頻道模型-內容模型管理”,選擇”普通文章-欄位管理-新增新欄位“
注意紅色框選的地方,後面的講解會說到。
二、 刪除方法:
1、第一步,“核心-頻道模型-內容模型管理”,選擇”普通文章-欄位管理“,刪除”模型欄位配置“中新增加的內容,即下圖中紅色框選部分。
這一步實際上是更改表dede_channeltype中的fieldset欄位的值。
2、第二步,若在新增自字義欄位時,勾選了”使欄位可以在列表的底層模板中。。。。“,則執行這一步,否則跳過即可。
第二步,“核心-頻道模型-內容模型管理”,選擇”普通文章-基本設定“,修改”列表附加欄位“,刪除其中新增加的部分。如下圖,將”body,qq“改為"body"
這一步實際上是更改表dede_channeltype中的listfields欄位的值。
3、第三步,刪除表dede_addonarticle中我們新增加的欄位。
alter table dede_addonarticle drop qq;
完成這三步後,就將我們增加的自定義欄位徹底刪除了。
三、原理
我們採用逆向思維分析我們這樣做的原理,我們檢視dedecms源程式,看它在增加自定義欄位時都幹了什麼事情,我們在刪除時,把它乾的事情撤消掉,就達到了我們的目的。
新增自字義欄位時涉及到的主要檔案:mychannel_field_add.php、inc_admin_channel.php
一、mychannel_field_add.php中的save方法,下面程式碼中我用/************ *********/註釋的部分,是執行的主要內容
if($action=='save') { //修改欄位配置資訊 $dfvalue = trim($vdefault); $isnull = ($isnull==1 ? "true" : "false"); $mxlen = $maxlength; if(preg_match("#^(select|radio|checkbox)$#i", $dtype)) { if(!preg_match("#,#", $dfvalue)) { ShowMsg("你設定了欄位為 {$dtype} 型別,必須在預設值中指定元素列表,如:'a,b,c' ","-1"); exit(); } } if($dtype=='stepselect') { $arr = $dsql->GetOne("SELECT * FROM `#@__stepselect` WHERE egroup='$fieldname' "); if(!is_array($arr)) { ShowMsg("你設定了欄位為聯動型別,但系統中沒找到與你定義的欄位名相同的聯動組名!","-1"); exit(); } } //模型資訊 $row = $dsql->GetOne("SELECT fieldset,addtable,issystem FROM `#@__channeltype` WHERE id='$id'"); $fieldset = $row['fieldset']; $dtp = new DedeTagParse(); $dtp->SetNameSpace("field", "<", ">"); $dtp->LoadSource($fieldset); $trueTable = $row['addtable']; //檢測被修改的欄位型別 $fieldinfos = GetFieldMake($dtype, $fieldname, $dfvalue, $mxlen); $ntabsql = $fieldinfos[0]; $buideType = $fieldinfos[1]; /***********給dede_addonarticle表增加欄位***********/ $rs = $dsql->ExecuteNoneQuery(" ALTER TABLE `$trueTable` ADD $ntabsql "); if(!$rs) { $gerr = $dsql->GetError(); ShowMsg("增加欄位失敗,錯誤提示為:".$gerr,"javascript:;"); exit(); } //檢測舊配置資訊,並替換為新配置 $ok = FALSE; $fieldname = strtolower($fieldname); if(is_array($dtp->CTags)) { foreach($dtp->CTags as $tagid=>$ctag) { if($fieldname == strtolower($ctag->GetName())) { $dtp->Assign($tagid, stripslashes($fieldstring), FALSE); $ok = true; break; } } $oksetting = $ok ? $dtp->GetResultNP() : $fieldset."\n".stripslashes($fieldstring); } else { $oksetting = $fieldset."\r\n".stripslashes($fieldstring); } $addlist = GetAddFieldList($dtp,$oksetting); $oksetting = addslashes($oksetting); /***********修改表dede_channeltype中的fieldset和listfields欄位**********/ $rs = $dsql->ExecuteNoneQuery("UPDATE `#@__channeltype` SET fieldset='$oksetting',listfields='$addlist' WHERE id='$id' "); if(!$rs) { $grr = $dsql->GetError(); ShowMsg("儲存節點配置出錯!".$grr, "javascript:;"); exit(); } ShowMsg("成功增加一個欄位!", "mychannel_edit.php?id={$id}&dopost=edit&openfield=1"); exit(); }
二、在inc_admin_channel中的GetAddFieldList方法中判斷是否勾選了"使欄位可以在列表的底層模板中。。。。"
function GetAddFieldList(&$dtp,&$oksetting)
{
$oklist = '';
$dtp->SetNameSpace("field","<",">");
$dtp->LoadSource($oksetting);
if(is_array($dtp->CTags))
{
foreach($dtp->CTags as $tagid=>$ctag)
{
/***********在這裡判斷是否勾選了"使欄位可以在列表的底層模板中。。。。"************/
if($ctag->GetAtt('islist')==1)
{
$oklist .= ($oklist=='' ? strtolower($ctag->GetName()) : ','.strtolower($ctag->GetName()) );
}
}
}
return $oklist;
}