<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 完整的插件運行流程 ### 插件安裝流程 首先 ,我們打開Editor插件的定義類 ~~~ <?php // +---------------------------------------------------------------------- // | OneThink [ WE CAN DO IT JUST THINK IT ] // +---------------------------------------------------------------------- // | Copyright (c) 2013 http://www.onethink.cn All rights reserved. // +---------------------------------------------------------------------- // | Author: yangweijie <yangweijiester@gmail.com> <code-tech.diandian.com> // +---------------------------------------------------------------------- namespace Addons\Editor; use Common\Controller\Addon; /** * 編輯器插件 * @author yangweijie <yangweijiester@gmail.com> */ class EditorAddon extends Addon{ public $info = array( 'name'=>'Editor', 'title'=>'前臺編輯器', 'description'=>'用于增強整站長文本的輸入和顯示', 'status'=>1, 'author'=>'thinkphp', 'version'=>'0.1' ); public function install(){ return true; } public function uninstall(){ return true; } /** * 編輯器掛載的文章內容鉤子 * @param array('name'=>'表單name','value'=>'表單對應的值') */ public function documentEditFormContent($data){ $this->assign('addons_data', $data); $this->assign('addons_config', $this->getConfig()); $this->display('content'); } /** * 討論提交的鉤子使用編輯器插件擴展 * @param array('name'=>'表單name','value'=>'表單對應的值') */ public function topicComment ($data){ $this->assign('addons_data', $data); $this->assign('addons_config', $this->getConfig()); $this->display('content'); } } ~~~ 整個插件就是一個特殊的繼承了?`Addon`抽象類的子類。必須實現 install和uninstall方法。 然后必須有一個自己的info屬性,作為插件自己的信息。name、titile、description、status、author、version這6個是必須的。到時候后臺列表里在未安裝時會讀取插件信息,顯示出來。status為1或者0,表示安裝插件后是否立即啟用。 效果見下圖:?![image](http://ww2.sinaimg.cn/mw1024/50075709jw1e8vcw886rhj21320b2tay.jpg)install和uninstall方法用于后臺插件安裝和卸載時候調用。返回true或者false用于告訴后臺我安裝卸載的準備工作是否做好了。比如我安裝時候創建了某些表,創建成功可以安裝,不成功提示錯誤。卸載前應該將安裝時做的操作恢復到安裝前狀態。 其次,插件被安裝后才能配置插件,卸載后會同時去除鉤子處掛載的插件名,安裝會添加鉤子對應的插件名。 后臺AddonsController.class.php ~~~ /** * 安裝插件 */ public function install(){ $addon_name = trim(I('addon_name')); $class = get_addon_class($addon_name); if(!class_exists($class)) $this->error('插件不存在'); $addons = new $class; $info = $addons->info; if(!$info || !$addons->checkInfo())//檢測信息的正確性 $this->error('插件信息缺失'); session('addons_install_error',null); $install_flag = $addons->install(); if(!$install_flag){ $this->error('執行插件預安裝操作失敗'.session('addons_install_error')); } $addonsModel = D('Addons'); $data = $addonsModel->create($info); if(is_array($addons->admin_list) && $addons->admin_list !== array()){ $data['has_adminlist'] = 1; }else{ $data['has_adminlist'] = 0; } if(!$data) $this->error($addonsModel->getError()); if($addonsModel->add($data)){ $config = array('config'=>json_encode($addons->getConfig())); $addonsModel->where("name='{$addon_name}'")->save($config); $hooks_update = D('Hooks')->updateHooks($addon_name); if($hooks_update){ S('hooks', null); $this->success('安裝成功'); }else{ $addonsModel->where("name='{$addon_name}'")->delete(); $this->error('更新鉤子處插件失敗,請卸載后嘗試重新安裝'); } }else{ $this->error('寫入插件數據失敗'); } } ~~~ 實例化插件類->插件info是否正確->執行install方法,預安裝操作->添加插件數據到數據庫Addons表和Hooks表 每個步驟出錯都會提示,install 方法中錯誤用?`session('addons_install_error', 'error')`傳遞。 ### 插件卸載流程 卸載流程和安裝相反 后臺AddonsController.class.php ~~~ /** * 卸載插件 */ public function uninstall(){ $addonsModel = M('Addons'); $id = trim(I('id')); $db_addons = $addonsModel->find($id); $class = get_addon_class($db_addons['name']); $this->assign('jumpUrl',U('index')); if(!$db_addons || !class_exists($class)) $this->error('插件不存在'); session('addons_uninstall_error',null); $addons = new $class; $uninstall_flag = $addons->uninstall(); if(!$uninstall_flag) $this->error('執行插件預卸載操作失敗'.session('addons_uninstall_error')); $hooks_update = D('Hooks')->removeHooks($db_addons['name']); if($hooks_update === false){ $this->error('卸載插件所掛載的鉤子數據失敗'); } S('hooks', null); $delete = $addonsModel->where("name='{$db_addons['name']}'")->delete(); if($delete === false){ $this->error('卸載插件失敗'); }else{ $this->success('卸載成功'); } } ~~~ 實例化插件類->執行預卸載->卸載插件所掛載過的鉤子處信息->刪除插件文件。 每個步驟出錯都會提示,install 方法中錯誤用`session('addons_uninstall_error', 'error')`傳遞。 ### 插件運行流程 hook函數調用Hook類的listen靜態方法觸發鉤子->獲取鉤子掛載的開啟的插件->執行對應插件實現的鉤子同名方法(這個在init_hooks函數會初始化) 代碼上就是如下的過程: ~~~ hook('documentEditFormContent'); ~~~ 然后hook函數遍歷 Hook類里的$tag屬性,知道有哪些插件可被調用,接下來去讀取配置和狀態,啟用就去執行鉤子 ~~~ /** * 處理插件鉤子 * @param string $hook 鉤子名稱 * @param mixed $params 傳入參數 * @return void */ function hook($hook,$params=array()){ \Think\Hook::listen($hook,$params); } ~~~ 而Hook::listen方法里面 ~~~ /** * 監聽標簽的插件 * @param string $tag 標簽名稱 * @param mixed $params 傳入參數 * @return void */ static public function listen($tag, &$params=NULL) { if(isset(self::$tags[$tag])) { if(APP_DEBUG) { G($tag.'Start'); trace('[ '.$tag.' ] --START--','','INFO'); } foreach (self::$tags[$tag] as $name) { APP_DEBUG && G($name.'_start'); $result = self::exec($name, $tag,$params); if(APP_DEBUG){ G($name.'_end'); trace('Run '.$name.' [ RunTime:'.G($name.'_start',$name.'_end',6).'s ]','','INFO'); } if(false === $result) { // 如果返回false 則中斷插件執行 return ; } } if(APP_DEBUG) { // 記錄行為的執行日志 trace('[ '.$tag.' ] --END-- [ RunTime:'.G($tag.'Start',$tag.'End',6).'s ]','','INFO'); } } return; } /** * 執行某個插件 * @param string $name 插件名稱 * @param Mixed $params 傳入的參數 * @return void */ static public function exec($name, $tag,&$params=NULL) { if(false === strpos($name,'\\')) { // 插件(多個入口) $class = "Addons\\{$name}\\{$name}Addon"; }else{ // 行為擴展(只有一個run入口方法) $class = $name.'Behavior'; $tag = 'run'; } $addon = new $class(); return $addon->$tag($params); } #實例化一個插件類,我們有get_addon_classs()函數,傳入插件名即可或得插件類名,然后直接new 就行了,區分大小寫 $addons_class = new get_addon_classs($addon_name); ~~~ `$addon->$tag()`?這個方法就是去執行鉤子處掛載的和鉤子同名的插件方法。 這個方法里可以display渲染模板,默認插件的模板就在插件目錄下,比如Editor插件類里用的`$this->display('content');`。 如果你想有目錄層可以傳入`目錄/模板`這樣的參數,這樣是不支持主題的,如果要支持主題,也可以傳入具體的模板路徑,使用T函數如`T('Addons://Attachment@Article/edit')`這樣,到時候想切換主題了,T函數定位模板之前C('DEFAULT_THEME','default')這樣就行了。 當然這個方法支持傳參,只允許一個,為了能實現引用。所以多個參數,請封裝成數組,傳入hook函數的第二個參數。 執行完畢,這個鉤子的某個插件前臺功能方法就運行完了。 插件被禁用,鉤子處的插件不會被執行該同名方法,并且插件后臺列表里不會出現該插件的列表。 插件不光前臺能用 ,后臺有鉤子,并且插件里實現了該鉤子,也可以用。為了前后臺編輯器插件可以配置不同的編輯器,我們復制了一份Editor插件,改名為EditroForAdmin了。 還有后臺首頁,其實是用AdminIndex 鉤子掛載了幾個插件。 后臺中,插件默認會在 插件列表里出現。默認沒有安裝過的會顯示在前面。基本的數據字段都是讀取的插件類里的info屬性數組。插件未安裝的時候是不可以設置的。 假如插件需要url訪問,就必須插件里有Controller目錄和tp結構一樣。 只不過生成這個方法的用`addons_url('插件名://控制器名/操作方法')`,生成訪問url。并且訪問權限由插件去做。具體寫法,參照附件Attachment插件 里的控制器寫法。和模板里url調用。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看