discuz作為國內流行的論壇系統,可謂造福了不少趣味相投的網友們。它讓天南地北、國內外有着共同興趣愛好的人們聚集在一起,分享彼此的喜怒哀樂、心得體會。然而作為discuz的使用者之一,還是個碼農,然而對discuz的系統架構和二次開發了解得並不多。前段時間有個朋友找到我說能不能幫忙開發一個特殊主題插件,雖然自己沒開發過discuz的插件,但就discuz的流行程度而言,相信開發資料和開發群體應該不少,於是就答應了。
開發之前網上搜索了一通資料,找到discuz官方二次開發文檔看了看,然后又找來一些其它插件參考了下,於是就開干了。由於開發的是一個特殊主題的插件,因此參考官方的開發文檔http://faq.comsenz.com/library/plug/plugin/plugin_specialthread.htm,並利用discuz官方提供的開發工具生成了個簡單的插件(插件開發工具可在此下載:http://addon.discuz.com/resource/develop.zip)。
我們看看怎么開發一個特殊主題的插件吧,要是想直接看我犯了哪樣的愚蠢錯誤,你可以直接拉到文章的末尾。
一、插件開發步驟:
1、下載插件開發工具並創建插件:
插件開發工具下載並解壓至web根目錄。然后通過http://你的域名/develop.php訪問插件開發工具,我的是http://127.0.0.1:8080/develop.php。點擊“創建新插件”,然后一步步根據提示填寫即可。
此處,你還可以檢測插件前綴是否被占用,方便后續發布到插件市場。編輯腳本這一步填寫自身的特殊腳本名稱即可。
創建完成以后可以通過設計腳本,導出插件包。
這樣就已經將一個插件的原型都生成了,將它拷貝到/source/plugin/目錄並解壓。
2、開啟開發者模式並設置特殊主題
開啟開發者模式,在config/config_global.php 后邊填一行$_config['plugindeveloper'] = 1;值為1表示開啟開發者模式,為2則表示同時開啟潛入點提示。填寫完成之后刷新后台管理界面,依次找到應用-->插件-->找到剛剛創建的插件並點擊設計,即可編輯剛剛創建的插件腳本了。這里仍然需要設置一下特殊主題。
程序模塊名稱為前面插件創建時填寫的名稱。我們可以看看gfpaimai.class.php的具體代碼
<?php /** * [gfpaimai(gfpaimai.{modulename})] (C)2015-2099 Powered by 版權所有. * Version: 1.0.0 * Date: 2015-7-11 10:05 */ if(!defined('IN_DISCUZ')) { exit('Access Denied'); } class plugin_gfpaimai { //TODO - Insert your code here } class threadplugin_gfpaimai { public $name = 'XX主題'; //主題類型名稱 public $iconfile = 'icon.gif'; //發布主題鏈接中的前綴圖標 public $buttontext = '發布xx主題'; //發帖時按鈕文字 /** * 發主題時頁面新增的表單項目 * @param Integer $fid: 版塊ID * @return string 通過 return 返回即可輸出到發帖頁面中 */ public function newthread($fid) { //TODO - Insert your code here return 'TODO:newthread'; } /** * 主題發布前的數據判斷 * @param Integer $fid: 版塊ID */ public function newthread_submit($fid) { //TODO - Insert your code here } /** * 主題發布后的數據處理 * @param Integer $fid: 版塊ID * @param Integer $tid: 當前帖子ID */ public function newthread_submit_end($fid, $tid) { //TODO - Insert your code here } /** * 編輯主題時頁面新增的表單項目 * @param Integer $fid: 版塊ID * @param Integer $tid: 當前帖子ID * @return string 通過 return 返回即可輸出到編輯主題頁面中 */ public function editpost($fid, $tid) { //TODO - Insert your code here return 'TODO:editpost'; } /** * 主題編輯前的數據判斷 * @param Integer $fid: 版塊ID * @param Integer $tid: 當前帖子ID */ public function editpost_submit($fid, $tid) { //TODO - Insert your code here } /** * 主題編輯后的數據處理 * @param Integer $fid: 版塊ID * @param Integer $tid: 當前帖子ID */ public function editpost_submit_end($fid, $tid) { //TODO - Insert your code here } /** * 回帖后的數據處理 * @param Integer $fid: 版塊ID * @param Integer $tid: 當前帖子ID */ public function newreply_submit_end($fid, $tid) { //TODO - Insert your code here } /** * 查看主題時頁面新增的內容 * @param Integer $tid: 當前帖子ID * @return string 通過 return 返回即可輸出到主題首貼頁面中 */ public function viewthread($tid) { //TODO - Insert your code here return 'TODO:viewthread'; } } ?>
這樣可以清晰地看到哪個函數是干什么用的,我們只需要將業務邏輯處理好即可。然而現實總是殘酷的,對於discuz不熟悉的同學這將是一個巨大的坑。至此特殊主題的骨架可以說已經搭建好了,那么怎樣才可以發帖呢?這個地方找了很久才知道是什么原因,最后發現是權限的問題。
3、設置板塊權限
論壇-->板塊管理,找到對應的板塊-->編輯-->帖子選項、權限相關
4、設置用戶組和管理組權限
用戶-->用戶組(管理組)-->選擇需要編輯的用戶組-->批量編輯-->勾選可以發布特殊主題的用戶組
至此,沒什么意外的話,就可以發帖了;相信大部分開發者到這一步也可以發帖了。可是偷懶的我,必然要為這個偷懶付出代價的。
二、我范的愚蠢錯誤?還是discuz本身的bug呢?
上訴步驟完成以后,為了快速地看看效果。直接從別的插件里面復制了一個模板newthread.htm到template目錄下,然后修改了gfpaimai.class.php的newthread函數,讓其加載自定義模板。
public function newthread($fid) { //TODO - Insert your code here include template("gfpaimai:newthread"); //return 'TODO:newthread'; return $return; }
修改驗證函數
public function newthread_submit($fid) { //TODO - Insert your code here $message=getgpc('message'); //對內容判斷 if( empty($message) || strlen($message)<15 ) { showmessage("對不起,請填寫交易內容和具體要求,不少於15字!"); } }
此時,無論我編輯框里面輸入多少個字符都顯示,"對不起,請填寫交易內容和具體要求,不少於15字!"。用var_dump($message)查看,message確實為空,$_GET的結果也為空。無論我怎么測試都是如此,對比了下其它插件,發現他們也都是這么寫的。我就郁悶了,怎么會有這樣的問題出來呢?難道又是權限問題?可是檢查了一遍又一遍,沒發現哪里有問題。這么來回不知道折騰了多少回,實在沒轍,加幾個Q群請教請教這方面的老大吧。加了幾個群,大多都沒人回。后來一個discuz插件開發群的老大“風子”的指點下找到了問題所在。
去掉自定義模板查看是否可以獲取message的內容,也就是去掉newthread函數的
include template("gfpaimai:newthread");
測試發現可以獲取到message的內容,瞬間千萬個草泥馬在奔騰。
好了,既然知道是自定義模板的問題。那么接下來看看是模板什么地方導致無法獲取message吧。於是一段段代碼去掉,最后的最后。你們也想到了的,它出現了。你可以想象下我當時的表情,欲哭無淚以外便是千萬個草泥馬在奔騰。最后居然是一個hidden名稱導致的,代碼如下。
<input type="hidden" name="tradeflag" id="tradeflag" value="1"/>
於是刪掉,再次測試。尼瑪的,果然出來了。於是改個名字再次測試,尼瑪的,還是出來了。看到這,你有什么感受?反正我是欲哭無淚了,看來解決bug和產生新的bug是程序猿的宿命。
三、問題的反思
問題解決了,好吧,接下來反思下為什么會這樣呢?
1、萬惡的習慣,復制的代碼,偷懶不得呀!越是想偷懶,越是花更多的時間來調試。
2、難道不同插件相同的name會導致其中一個用不了?如果是這樣,為什么其他的相同又沒事,偏偏就這個name為tradeflag的hidden值就如此呢?搞不懂,tell me why?不知道有沒有哪位碰到過這樣的問題,如果知道是什么原因不妨告訴我(又在偷懶了。。。。)。
參考資料:
http://faq.comsenz.com/library/plug/plugin/plugin_specialthread.htm
http://www.discuz.1314study.com/t/78913.html