├── .gitattributes ├── .gitignore ├── Action.php ├── Addons ├── DailySentence │ └── Addon.php ├── DrivingTest │ └── Addon.php ├── IdCard │ └── Addon.php ├── IpTaoBao │ └── Addon.php ├── Moral │ └── Addon.php └── Phone │ └── Addon.php ├── Images └── UserHeadDefault.jpg ├── Page ├── Addons.php ├── Config.php ├── CustomReply.php ├── Menus.php └── Users.php ├── Plugin.php ├── README.md └── Widget ├── Addons.php ├── Config.php ├── CustomReply.php ├── Menus.php ├── Users.php ├── Utils.php └── WeChat.php /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /Action.php: -------------------------------------------------------------------------------- 1 | db = Typecho_Db::get(); 22 | /** 初始化常用组件 */ 23 | $this->options = $this->widget('Widget_Options'); 24 | $this->user = $this->widget('Widget_User'); 25 | } 26 | public function execute() {} 27 | 28 | public function valid() { 29 | $echoStr = $this->request->get('echostr'); 30 | if($this->checkSignature($this->options->WCH_token)){ 31 | echo $echoStr; 32 | exit; 33 | } 34 | } 35 | 36 | private function checkSignature($token) { 37 | $signature = $this->request->get('signature'); 38 | $timestamp = $this->request->get('timestamp'); 39 | $nonce = $this->request->get('nonce'); 40 | 41 | $tmpArr = array($token, $timestamp, $nonce); 42 | sort($tmpArr, SORT_STRING); 43 | $tmpStr = implode($tmpArr); 44 | $tmpStr = sha1($tmpStr); 45 | 46 | if($tmpStr == $signature){ 47 | return true; 48 | }else{ 49 | return false; 50 | } 51 | } 52 | 53 | /** 54 | * 数据 55 | * 56 | */ 57 | public function postAction(){ 58 | Typecho_Widget::widget('WeChatHelper_Widget_WeChat')->action(); 59 | /* 60 | $dir = __TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__ . '/WeChatHelper'; 61 | $myfile = $dir.'/wechatDebug.txt'; 62 | //echo $myfile; 63 | $file_pointer = @fopen($myfile,"a"); 64 | @fwrite($file_pointer, $this->get_http_raw()); 65 | @fclose($file_pointer); 66 | */ 67 | } 68 | 69 | public function action(){ 70 | if($this->request->is('valid')){ 71 | if($this->request->isGet()){ 72 | $this->valid(); 73 | }else if($this->request->isPost()){ 74 | $this->postAction(); 75 | } 76 | }else if($this->request->is('config')){ //插件设置业务 77 | Typecho_Widget::widget('WeChatHelper_Widget_Config')->action(); 78 | }else if($this->request->is('customreply')){ //自定义回复业务 79 | Typecho_Widget::widget('WeChatHelper_Widget_CustomReply')->action(); 80 | }else if($this->request->is('users')){ //用户业务 81 | Typecho_Widget::widget('WeChatHelper_Widget_Users')->action(); 82 | }else if($this->request->is('menus')){ //菜单业务 83 | Typecho_Widget::widget('WeChatHelper_Widget_Menus')->action(); 84 | } 85 | /* 86 | if($this->request->isGet()){ 87 | $this->on($this->request->is('valid'))->valid(); 88 | if($this->request->is('users')){ //用户业务 89 | Typecho_Widget::widget('WeChatHelper_Widget_Users')->action(); 90 | } 91 | } 92 | if($this->request->isPost()){ 93 | $this->on($this->request->is('valid'))->postAction(); 94 | if($this->request->is('config')){ //插件设置业务 95 | Typecho_Widget::widget('WeChatHelper_Widget_Config')->action(); 96 | }else if($this->request->is('customreply')){ //自定义回复业务 97 | Typecho_Widget::widget('WeChatHelper_Widget_CustomReply')->action(); 98 | }else if($this->request->is('users')){ //用户业务 99 | Typecho_Widget::widget('WeChatHelper_Widget_Users')->action(); 100 | }else if($this->request->is('menus')){ //菜单业务 101 | Typecho_Widget::widget('WeChatHelper_Widget_Menus')->action(); 102 | } 103 | } 104 | */ 105 | } 106 | } 107 | ?> -------------------------------------------------------------------------------- /Addons/DailySentence/Addon.php: -------------------------------------------------------------------------------- 1 | result = $result; 19 | $this->postObj = $postObj; 20 | $this->params = $params; 21 | } 22 | 23 | public function execute(){ 24 | $client = Typecho_Http_Client::get(); 25 | //金山词霸http://open.iciba.com/dsapi/ 26 | //词海http://en.dict.cn/api/article/daily 27 | $response = $client->send('http://en.dict.cn/api/article/daily'); 28 | $response = json_decode($response); 29 | $text = $response->en.chr(10).chr(10); 30 | $text .= $response->ch; 31 | $this->result->setMsgType(MessageTemplate::TEXT)->setText($text)->send(); 32 | } 33 | } 34 | ?> 35 | -------------------------------------------------------------------------------- /Addons/DrivingTest/Addon.php: -------------------------------------------------------------------------------- 1 | result = $result; 16 | 17 | $this->data = array( 18 | array( 19 | 'title' => '驾校一点通模拟考试', 20 | 'description' => '', 21 | 'picurl' => '', 22 | 'url' => '' 23 | ), 24 | array( 25 | 'title' => '小车考试科目一 车型:C1 C2照', 26 | 'description' => '', 27 | 'picurl' => '', 28 | 'url' => 'http://m.jxedt.com/mnks/indexlx.asp' 29 | ), 30 | array( 31 | 'title' => '货车考试科目一 车型:A2 B2照', 32 | 'description' => '', 33 | 'picurl' => '', 34 | 'url' => 'http://m.jxedt.com/mnks/indexlx.asp?type=b' 35 | ), 36 | array( 37 | 'title' => '客车考试科目一 车型:A1 A3 B1照', 38 | 'description' => '', 39 | 'picurl' => '', 40 | 'url' => 'http://m.jxedt.com/mnks/indexlx.asp?type=a' 41 | ), 42 | array( 43 | 'title' => '安全文明科目四 车型:C1 C2 B2照', 44 | 'description' => '', 45 | 'picurl' => '', 46 | 'url' => 'http://m.jxedt.com/mnks/indexlx.asp?type=s' 47 | ) 48 | ); 49 | } 50 | 51 | public function execute(){ 52 | foreach ($this->data as $row) { 53 | $this->result->addItem($row); 54 | } 55 | $this->result->setMsgType(MessageTemplate::NEWS)->send(); 56 | } 57 | } 58 | ?> 59 | -------------------------------------------------------------------------------- /Addons/IdCard/Addon.php: -------------------------------------------------------------------------------- 1 | result = $result; 21 | $this->postObj = $postObj; 22 | $this->params = $params; 23 | 24 | $this->query = array('app' => 'idcard.get', 25 | 'format' => 'json', 26 | 'appkey' => '10755', 27 | 'sign' => 'ce865fa86edc8cdbfe59b3cc27fe621b', 28 | 'idcard' => ''); 29 | } 30 | 31 | public function execute(){ 32 | $this->get(); 33 | } 34 | 35 | private function get(){ 36 | if($this->params){ 37 | $this->query['idcard'] = $this->params['param']; 38 | } 39 | $this->result->setMsgType(MessageTemplate::TEXT); 40 | $client = Typecho_Http_Client::get(); 41 | $response = $client->setQuery($this->query)->send($this->url); 42 | $response = json_decode($response); 43 | 44 | if($response->success){ 45 | $text = '号码:'.$response->result->idcard.chr(10); 46 | $text .= '地区:'.$response->result->att.chr(10); 47 | $text .= '出生:'.$response->result->born.chr(10); 48 | $text .= '性别:'.$response->result->sex; 49 | }else{ 50 | $text = $response->msg; 51 | } 52 | $this->result->setText($text)->send(); 53 | } 54 | } 55 | ?> 56 | -------------------------------------------------------------------------------- /Addons/IpTaoBao/Addon.php: -------------------------------------------------------------------------------- 1 | result = $result; 21 | $this->postObj = $postObj; 22 | $this->params = $params; 23 | 24 | $this->query = array('ip' => ''); 25 | } 26 | 27 | public function execute(){ 28 | if($this->params){ 29 | $this->query['ip'] = $this->params['param']; 30 | } 31 | $this->result->setMsgType(MessageTemplate::TEXT); 32 | $client = Typecho_Http_Client::get(); 33 | $response = $client->setQuery($this->query)->send($this->url); 34 | $response = json_decode($response); 35 | if(!$response->code){ 36 | $text = 'IP:'.$response->data->ip.chr(10); 37 | $text .= '国家:'.$response->data->country.chr(10); 38 | $text .= '地区:'.$response->data->area.chr(10); 39 | $text .= '省份:'.$response->data->region.chr(10); 40 | $text .= '城市:'.$response->data->city.chr(10); 41 | $text .= '服务商:'.$response->data->isp; 42 | }else{ 43 | $text = 'IP地址错误,请输入正确地址!'; 44 | } 45 | $this->result->setText($text)->send(); 46 | } 47 | } 48 | ?> 49 | -------------------------------------------------------------------------------- /Addons/Moral/Addon.php: -------------------------------------------------------------------------------- 1 | result = $result; 18 | $this->postObj = $postObj; 19 | $this->params = $params; 20 | } 21 | 22 | public function execute(){ 23 | $name = str_replace("+", "", $this->params['param']); 24 | $f = mb_substr($name, 0, 1, 'utf-8'); 25 | $s = mb_substr($name, 1, 1, 'utf-8'); 26 | $w = mb_substr($name, 2, 1, 'utf-8'); 27 | $x = mb_substr($name, 3, 1, 'utf-8'); 28 | $n = ($this->getUnicodeFromUTF8($f) + $this->getUnicodeFromUTF8($s) + $this->getUnicodeFromUTF8($w) + $this->getUnicodeFromUTF8($x)) % 100; 29 | $addd=''; 30 | if(empty($name)) { 31 | $addd="大哥不要玩我啊,名字都没有你想算什么!"; 32 | } else if ($n <= 0) { 33 | $addd ="你一定不是人吧?怎么一点人品都没有?!"; 34 | } else if($n > 0 && $n <= 5) { 35 | $addd ="算了,跟你没什么人品好谈的..."; 36 | } else if($n > 5 && $n <= 10) { 37 | $addd ="是我不好...不应该跟你谈人品问题的..."; 38 | } else if($n > 10 && $n <= 15) { 39 | $addd ="杀过人没有?放过火没有?你应该无恶不做吧?"; 40 | } else if($n > 15 && $n <= 20) { 41 | $addd ="你貌似应该三岁就偷看隔壁大妈洗澡的吧..."; 42 | } else if($n > 20 && $n <= 25) { 43 | $addd ="你的人品之低下实在让人惊讶啊..."; 44 | } else if($n > 25 && $n <= 30) { 45 | $addd ="你的人品太差了。你应该有干坏事的嗜好吧?"; 46 | } else if($n > 30 && $n <= 35) { 47 | $addd ="你的人品真差!肯定经常做偷鸡摸狗的事..."; 48 | } else if($n > 35 && $n <= 40) { 49 | $addd ="你拥有如此差的人品请经常祈求佛祖保佑你吧..."; 50 | } else if($n > 40 && $n <= 45) { 51 | $addd ="老实交待..那些论坛上面经常出现的偷拍照是不是你的杰作?"; 52 | } else if($n > 45 && $n <= 50) { 53 | $addd ="你随地大小便之类的事没少干吧?"; 54 | } else if($n > 50 && $n <= 55) { 55 | $addd ="你的人品太差了..稍不小心就会去干坏事了吧?"; 56 | } else if($n > 55 && $n <= 60) { 57 | $addd ="你的人品很差了..要时刻克制住做坏事的冲动哦.."; 58 | } else if($n > 60 && $n <= 65) { 59 | $addd ="你的人品比较差了..要好好的约束自己啊.."; 60 | } else if($n > 65 && $n <= 70) { 61 | $addd ="你的人品勉勉强强..要自己好自为之.."; 62 | } else if($n > 70 && $n <= 75) { 63 | $addd ="有你这样的人品算是不错了.."; 64 | } else if($n > 75 && $n <= 80) { 65 | $addd ="你有较好的人品..继续保持.."; 66 | } else if($n > 80 && $n <= 85) { 67 | $addd ="你的人品不错..应该一表人才吧?"; 68 | } else if($n > 85 && $n <= 90) { 69 | $addd ="你的人品真好..做好事应该是你的爱好吧.."; 70 | } else if($n > 90 && $n <= 95) { 71 | $addd ="你的人品太好了..你就是当代活雷锋啊..."; 72 | } else if($n > 95 && $n <= 99) { 73 | $addd ="你是世人的榜样!"; 74 | } else if($n > 100 && $n < 105) { 75 | $addd ="天啦!你不是人!你是神!!!"; 76 | }else if($n > 105 && $n < 999) { 77 | $addd="你的人品已经过 100 人品计算器已经甘愿认输,3秒后人品计算器将自杀啊"; 78 | } else if($n > 999) { 79 | $addd ="你的人品竟然负溢出了...我对你无语.."; 80 | } 81 | $this->result->setText($name."的人品分数为:" . $n . "\n". $addd)->setMsgType(MessageTemplate::TEXT)->send(); 82 | } 83 | 84 | function getUnicodeFromUTF8($word) { 85 | if (is_array( $word)) 86 | $arr = $word; 87 | else 88 | $arr = str_split($word); 89 | $bin_str = ''; 90 | foreach ($arr as $value) 91 | $bin_str .= decbin(ord($value)); 92 | $bin_str = preg_replace('/^.{4}(.{4}).{2}(.{6}).{2}(.{6})$/','$1$2$3', $bin_str); 93 | return bindec($bin_str); 94 | } 95 | } 96 | ?> 97 | -------------------------------------------------------------------------------- /Addons/Phone/Addon.php: -------------------------------------------------------------------------------- 1 | result = $result; 21 | $this->postObj = $postObj; 22 | $this->params = $params; 23 | 24 | $this->query = array('app' => 'phone.get', 25 | 'format' => 'json', 26 | 'appkey' => '10755', 27 | 'sign' => 'ce865fa86edc8cdbfe59b3cc27fe621b', 28 | 'phone' => ''); 29 | } 30 | 31 | public function execute(){ 32 | $this->get(); 33 | } 34 | 35 | private function get(){ 36 | if($this->params){ 37 | $this->query['phone'] = $this->params['param']; 38 | } 39 | $this->result->setMsgType(MessageTemplate::TEXT); 40 | $client = Typecho_Http_Client::get(); 41 | $response = $client->setQuery($this->query)->send($this->url); 42 | $response = json_decode($response); 43 | 44 | if($response->success){ 45 | $text = '号码:'.$response->result->phone.chr(10); 46 | $text .= '地区:'.$response->result->att.chr(10); 47 | $text .= '区号:'.$response->result->area.chr(10); 48 | $text .= '类型:'.$response->result->ctype; 49 | }else{ 50 | $text = $response->msg; 51 | } 52 | $this->result->setText($text)->send(); 53 | } 54 | } 55 | ?> 56 | -------------------------------------------------------------------------------- /Images/UserHeadDefault.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binjoo/WeChatHelper/b8a127f0651693089358f5af26dfbde9019eefd3/Images/UserHeadDefault.jpg -------------------------------------------------------------------------------- /Page/Addons.php: -------------------------------------------------------------------------------- 1 | 8 |
9 |
10 |
11 |
12 |

title);?>

13 |
14 |
15 |
16 |
17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | getAddons();?> 39 | 40 | $row) { ?> 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 |
58 |
59 |
60 |
61 |
62 | 67 | -------------------------------------------------------------------------------- /Page/Config.php: -------------------------------------------------------------------------------- 1 | type ? $request->type : '1'; 7 | ?> 8 |
9 |
10 |
11 |
12 |

title);?>

13 |
14 |
15 |
16 |
17 | 23 | 24 | baseForm()->render(); ?> 25 | 26 | deluxeForm()->render(); ?> 27 | 28 | thirdPartyForm()->render(); ?> 29 | 30 | creditForm()->render(); ?> 31 | 32 |
33 |
34 |
35 |
36 | -------------------------------------------------------------------------------- /Page/CustomReply.php: -------------------------------------------------------------------------------- 1 | 8 |
9 |
10 |
11 |

title);?>新增

12 |
13 |
14 |
15 |
16 |
17 |
18 | 19 |
20 | 21 | 24 |
25 |
26 | 37 |
38 |
39 | 40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | to($customreply); ?> 66 | have()): ?> 67 | next()): ?> 68 | 69 | 70 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
71 | keywords(); ?> 72 | type)) ?>content(); ?>status ? _e('激活') : _e('冻结'); ?>
85 |
86 |
87 |
88 | have()): ?> 89 |
    90 | pageNav(); ?> 91 |
92 | 93 |
94 |
95 |
96 | form()->render(); ?> 97 |
98 |
99 |
100 |
101 | 105 | 106 | 145 | 146 | -------------------------------------------------------------------------------- /Page/Menus.php: -------------------------------------------------------------------------------- 1 | 7 |
8 |
9 |
10 |

title);?>新增

11 |
12 |
13 |
14 |
15 |
16 |
17 | 18 |
19 | 20 | 23 |
24 |
25 | 34 |
35 |
36 | 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | to($menus);?> 56 | have()): ?> 57 | next()): ?> 58 | tr) ?>> 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
72 |
73 |
74 |
75 |
76 | form()->render(); ?> 77 |
78 |
79 |
80 |
81 | 85 | 86 | 103 | 104 | -------------------------------------------------------------------------------- /Page/Users.php: -------------------------------------------------------------------------------- 1 | siteUrl; 6 | ?> 7 |
8 |
9 |
10 |

title);?>

11 |
12 |
13 |
14 |
15 |
16 |
17 | 18 |
19 |
20 | 31 |
32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | to($users);?> 61 | have()): ?> 62 | next()): ?> 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
微信 OpenID:<?php _e($users->openid) ?>openid) ?>nickname) ?>sexVal) ?>address) ?>subscribeFormat) ?>credits) ?>bindVal) ?> 73 | 74 | 更新详情 75 |
85 |
86 |
87 | have()): ?> 88 |
    89 | pageNav(); ?> 90 |
91 | 92 |
93 |
94 |
95 |
96 |
97 | 102 | -------------------------------------------------------------------------------- /Plugin.php: -------------------------------------------------------------------------------- 1 | getAdapterName() || "Mysql" === $db->getAdapterName()){ 15 | /** 16 | * 创建关键字表 17 | */ 18 | $db->query("CREATE TABLE IF NOT EXISTS " . $db->getPrefix() . 'wch_keywords' . " ( 19 | `kid` int(11) NOT NULL AUTO_INCREMENT, 20 | `name` varchar(100) NOT NULL, 21 | `rid` int(11) NOT NULL, 22 | PRIMARY KEY (`kid`) 23 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"); 24 | /** 25 | * 创建自定义回复表 26 | */ 27 | $db->query("CREATE TABLE IF NOT EXISTS " . $db->getPrefix() . 'wch_reply' . " ( 28 | `rid` int(11) NOT NULL AUTO_INCREMENT, 29 | `keywords` varchar(200) DEFAULT NULL, 30 | `type` varchar(20) DEFAULT 'text', 31 | `command` varchar(20) DEFAULT NULL, 32 | `param` char(1) DEFAULT '0', 33 | `content` text, 34 | `status` char(1) DEFAULT '0', 35 | `created` int(10) DEFAULT '0', 36 | PRIMARY KEY (`rid`) 37 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"); 38 | /** 39 | * 创建用户管理表 40 | */ 41 | $db->query("CREATE TABLE IF NOT EXISTS " . $db->getPrefix() . 'wch_users' . " ( 42 | `uid` int(11) NOT NULL AUTO_INCREMENT, 43 | `openid` varchar(50) DEFAULT '', 44 | `nickname` varchar(100) DEFAULT '', 45 | `sex` char(1) DEFAULT '', 46 | `language` varchar(50) DEFAULT '', 47 | `city` varchar(50) DEFAULT '', 48 | `province` varchar(50) DEFAULT '', 49 | `country` varchar(50) DEFAULT '', 50 | `headimgurl` varchar(200) DEFAULT '', 51 | `subscribe_time` int(10) DEFAULT '0', 52 | `credits` int(10) NOT NULL DEFAULT '0', 53 | `bind` int(3) DEFAULT '0', 54 | `status` char(1) DEFAULT '1', 55 | `created` int(10) DEFAULT '0', 56 | `synctime` int(10) DEFAULT '0', 57 | PRIMARY KEY (`uid`) 58 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"); 59 | /** 60 | * 创建自定义菜单表 61 | */ 62 | $db->query("CREATE TABLE IF NOT EXISTS " . $db->getPrefix() . 'wch_menus' . " ( 63 | `mid` int(11) NOT NULL AUTO_INCREMENT, 64 | `level` varchar(10) DEFAULT 'button', 65 | `name` varchar(200) DEFAULT '', 66 | `type` varchar(10) DEFAULT 'view', 67 | `value` varchar(200) DEFAULT '', 68 | `sort` int(3) DEFAULT '0', 69 | `order` int(3) DEFAULT '1', 70 | `parent` int(11) DEFAULT '0', 71 | `created` int(10) DEFAULT '0', 72 | PRIMARY KEY (`mid`) 73 | ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"); 74 | }else{ 75 | throw new Typecho_Plugin_Exception(_t('对不起, 本插件仅支持MySQL数据库。')); 76 | } 77 | 78 | $index = Helper::addMenu('微信助手'); 79 | Helper::addAction('WeChat', 'WeChatHelper_Action'); 80 | Helper::addPanel($index, 'WeChatHelper/Page/Config.php', '参数设置', '参数设置', 'administrator'); 81 | Helper::addPanel($index, 'WeChatHelper/Page/Users.php', '用户管理', '用户管理', 'administrator'); 82 | Helper::addPanel($index, 'WeChatHelper/Page/Menus.php', '自定义菜单', '自定义菜单', 'administrator'); 83 | Helper::addPanel($index, 'WeChatHelper/Page/CustomReply.php', '自定义回复', '自定义回复', 'administrator'); 84 | Helper::addPanel($index, 'WeChatHelper/Page/Addons.php', '插件扩展', '插件扩展', 'administrator'); 85 | return('微信助手已经成功激活,请进入设置Token!'); 86 | } 87 | 88 | public static function deactivate() { 89 | $db = Typecho_Db::get(); 90 | $options = Typecho_Widget::widget('Widget_Options'); 91 | if (isset($options->WeChatHelper_dropTable) && $options->WeChatHelper_dropTable) { 92 | if("Pdo_Mysql" === $db->getAdapterName() || "Mysql" === $db->getAdapterName()){ 93 | $db->query("drop table ".$db->getPrefix()."wch_keywords, ".$db->getPrefix()."wch_reply, ".$db->getPrefix()."wch_users, ".$db->getPrefix()."wch_menus"); 94 | $db->query($db->sql()->delete('table.options')->where('name like ?', "WeChatHelper_%")); 95 | } 96 | } 97 | $index = Helper::removeMenu('微信助手'); 98 | Helper::removePanel($index, 'WeChatHelper/Page/Config.php'); 99 | Helper::removePanel($index, 'WeChatHelper/Page/Users.php'); 100 | Helper::removePanel($index, 'WeChatHelper/Page/Menus.php'); 101 | Helper::removePanel($index, 'WeChatHelper/Page/CustomReply.php'); 102 | Helper::removePanel($index, 'WeChatHelper/Page/Addons.php'); 103 | Helper::removeAction('WeChat'); 104 | } 105 | 106 | public static function config(Typecho_Widget_Helper_Form $form) { 107 | } 108 | 109 | public static function personalConfig(Typecho_Widget_Helper_Form $form){} 110 | } 111 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 插件说明 ## 2 | 3 | - 版本: v2.2.1 4 | - 作者: [冰剑](https://github.com/binjoo) 5 | - 主页: 6 | 7 | `此插件涉及数据库操作,有潜在的未知风险,请慎用!` 8 | 9 | ## 插件特点 ## 10 | 11 | - 自定义菜单功能 12 | - 自定义回复功能 13 | - 第三方微信平台 14 | - 插件机制 15 | 16 | ## 使用方法 ## 17 | 18 | 1. 下载插件 19 | 2. 如果安装有老版本,请先卸载老版本,再删除插件文件 20 | 3. 将插件上传到 /usr/plugins/ 这个目录下 21 | 4. 登陆后台,在“控制台”下拉菜单中进入“插件管理” 22 | 5. 启用当前插件 23 | 6. 在“微信助手”下拉菜单中进入“参数设置”设置TOKEN相关信息 24 | 25 | ## 更新记录 ## 26 | #### v2.2.1 27 | - 优化参数设置安全提交路径; 28 | - 优化自定义回复安全提交路径; 29 | - 新增IP查询扩展; 30 | - 优化OPTIONS表KEY命名,方便扩展设置; 31 | 32 | #### v2.2.0 33 | - 新增自定义菜单功能; 34 | - 新增用户积分; 35 | - 新增关注奖励积分设置; 36 | - 优化参数设置规则; 37 | 38 | #### v2.1.0 39 | - 新增用户管理; 40 | - 新增插件扩展页面; 41 | - 优化设计插件规则; 42 | 43 | #### v2.0.0 44 | - 新增自定义回复功能; 45 | - 新增第三方微信平台; 46 | - 新增插件机制; 47 | 48 | #### v1.0.1 49 | - 新增 管理员用户绑定 50 | - 新增 管理员用户解除绑定 51 | - 新增 设置项验证码 52 | - 新增 设置项绑定用户 53 | 54 | #### v1.0.1 55 | - 新增 手气不错(命令 "l") 56 | - 新增 自定义订阅欢迎语 57 | - 新增 设置项默认图片 58 | - 新增 设置项返回图文数量 59 | - 新增 设置项访客评论排行榜数量 60 | - 新增 设置项日志截取字数 61 | - 修复 搜索日志BUG 62 | 63 | #### v1.0.0 64 | - 新增 最新日志(命令 "n") 65 | - 新增 随机日志(命令 "r") 66 | - 新增 搜索日志(命令 "s 关键词") 67 | - 新增 访客评论排行榜(命令 "f") 68 | -------------------------------------------------------------------------------- /Widget/Addons.php: -------------------------------------------------------------------------------- 1 | parseInfo($file); 25 | if ($info['name'] != '' && $info['package'] != '') { 26 | $result[$file] = $info; 27 | } 28 | } 29 | return $result; 30 | } 31 | 32 | public function parseInfo($file){ 33 | $tokens = token_get_all(file_get_contents($file)); 34 | $isDoc = false; 35 | 36 | $info = array( 37 | 'name' => '', 38 | 'author' => '', 39 | 'link' => '', 40 | 'package' => '', 41 | 'version' => '', 42 | 'description' => '', 43 | 'param' => '' 44 | ); 45 | 46 | foreach ($tokens as $token) { 47 | if (is_array($token) && T_DOC_COMMENT == $token[0]) { 48 | /** 分行读取 */ 49 | $lines = preg_split("(\r|\n)", $token[1]); 50 | foreach ($lines as $line) { 51 | $line = trim($line); 52 | if (!empty($line) && '*' == $line[0]) { 53 | $line = trim(substr($line, 1)); 54 | 55 | if (!empty($line) && '@' == $line[0]) { 56 | $line = trim(substr($line, 1)); 57 | $args = explode(' ', $line); 58 | $key = array_shift($args); 59 | if (isset($key)) { 60 | $info[$key] = trim(implode(' ', $args)); 61 | } 62 | } 63 | } 64 | } 65 | } 66 | } 67 | return $info; 68 | } 69 | 70 | public function action() { 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Widget/Config.php: -------------------------------------------------------------------------------- 1 | security->getIndex('action/WeChat?config&do=base'), Typecho_Widget_Helper_Form::POST_METHOD); 21 | 22 | $token = new Typecho_Widget_Helper_Form_Element_Text('token', NULL, NULL, 23 | _t('TOKEN'), _t('TOKEN内容自定义,需要与开发模式服务器配置中填写一致,推荐使用GUID。')); 24 | $token->value(isset($this->options->WCH_token) ? $this->options->WCH_token : ''); 25 | $form->addInput($token); 26 | 27 | $welcome = new Typecho_Widget_Helper_Form_Element_Textarea('welcome', NULL, NULL, _t('欢迎提示语'), _t('用户在关注公众号时,会发送欢迎的提示消息。')); 28 | $welcome->value(isset($this->options->WCH_welcome) ? $this->options->WCH_welcome : Utils::getDefaultMessage('welcome')); 29 | $form->addInput($welcome); 30 | 31 | $notfound = new Typecho_Widget_Helper_Form_Element_Textarea('notfound', NULL, NULL, _t('找不到提示语'), _t('没开启第三方平台搜索功能时,会发送找不到的提示消息。')); 32 | $notfound->value(isset($this->options->WCH_notfound) ? $this->options->WCH_notfound : Utils::getDefaultMessage('notfound')); 33 | $form->addInput($notfound); 34 | 35 | $dropTable = new Typecho_Widget_Helper_Form_Element_Radio('dropTable', 36 | array('1' => _t('开启'), '0' => _t('关闭')), 37 | NULL, _t('数据删除'), _t('开启后,禁用插件会删除插件设置数据和数据表。')); 38 | $dropTable->value(isset($this->options->WCH_dropTable) ? $this->options->WCH_dropTable : '0'); 39 | $form->addInput($dropTable); 40 | 41 | $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存设置')); 42 | $submit->input->setAttribute('class', 'btn primary'); 43 | $form->addItem($submit); 44 | 45 | return $form; 46 | } 47 | 48 | /** 49 | * 高级功能 50 | */ 51 | public function deluxeForm() { 52 | $form = new Typecho_Widget_Helper_Form($this->security->getIndex('action/WeChat?config&do=deluxe'), Typecho_Widget_Helper_Form::POST_METHOD); 53 | 54 | $appid = new Typecho_Widget_Helper_Form_Element_Text('appid', NULL, NULL, 55 | _t('APP ID'), _t('TOKEN内容自定义,需要与开发模式服务器配置中填写一致,推荐使用GUID。')); 56 | $appid->value(isset($this->options->WCH_appid) ? $this->options->WCH_appid : ''); 57 | $form->addInput($appid); 58 | 59 | $appsecret = new Typecho_Widget_Helper_Form_Element_Text('appsecret', NULL, NULL, 60 | _t('APP Secret'), _t('TOKEN内容自定义,需要与开发模式服务器配置中填写一致,推荐使用GUID。')); 61 | $appsecret->value(isset($this->options->WCH_appsecret) ? $this->options->WCH_appsecret : ''); 62 | $form->addInput($appsecret); 63 | 64 | $access_token = new Typecho_Widget_Helper_Form_Element_Hidden('access_token', NULL, NULL); 65 | $access_token->value(isset($this->options->WCH_access_token) ? $this->options->WCH_access_token : ''); 66 | $form->addInput($access_token); 67 | 68 | $expires_in = new Typecho_Widget_Helper_Form_Element_Hidden('expires_in', NULL, NULL); 69 | $expires_in->value(isset($this->options->WCH_expires_in) ? $this->options->WCH_expires_in : '0'); 70 | $form->addInput($expires_in); 71 | 72 | $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存设置')); 73 | $submit->input->setAttribute('class', 'btn primary'); 74 | $form->addItem($submit); 75 | 76 | return $form; 77 | } 78 | 79 | /** 80 | * 第三方 81 | */ 82 | public function thirdPartyForm() { 83 | $form = new Typecho_Widget_Helper_Form($this->security->getIndex('action/WeChat?config&do=thirdParty'), Typecho_Widget_Helper_Form::POST_METHOD); 84 | 85 | $thirdPartyUrl = new Typecho_Widget_Helper_Form_Element_Text('thirdPartyUrl', NULL, $this->options->WCH_thirdPartyUrl, 86 | _t('第三方平台链接'), _t('推荐平台:小i机器人')); 87 | $form->addInput($thirdPartyUrl); 88 | 89 | $thirdPartyToken = new Typecho_Widget_Helper_Form_Element_Text('thirdPartyToken', NULL, $this->options->WCH_thirdPartyToken, _t('第三方平台Token'), NULL); 90 | $form->addInput($thirdPartyToken); 91 | 92 | $thirdPartySearch= new Typecho_Widget_Helper_Form_Element_Radio('thirdPartySearch', 93 | array('1' => _t('开启'), '0' => _t('关闭')), 94 | NULL, _t('第三方平台搜索'), 95 | _t('所有在系统中找不到的关键字是否提交给第三方平台处理。')); 96 | $thirdPartySearch->value(isset($this->options->WCH_thirdPartySearch) ? $this->options->WCH_thirdPartySearch : '0'); 97 | $form->addInput($thirdPartySearch); 98 | 99 | $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存设置')); 100 | $submit->input->setAttribute('class', 'btn primary'); 101 | $form->addItem($submit); 102 | 103 | return $form; 104 | } 105 | 106 | /** 107 | * 积分设置 108 | */ 109 | public function creditForm() { 110 | $form = new Typecho_Widget_Helper_Form($this->security->getIndex('action/WeChat?config&do=credit'), Typecho_Widget_Helper_Form::POST_METHOD); 111 | 112 | $subscribe_credit = new Typecho_Widget_Helper_Form_Element_Text('subscribe_credit', NULL, NULL, 113 | _t('订阅积分'), _t('订阅后,初始赠送积分。')); 114 | $subscribe_credit->value(isset($this->options->WCH_subscribe_credit) ? $this->options->WCH_subscribe_credit : '0'); 115 | $form->addInput($subscribe_credit); 116 | 117 | $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存设置')); 118 | $submit->input->setAttribute('class', 'btn primary'); 119 | $form->addItem($submit); 120 | 121 | return $form; 122 | } 123 | 124 | public function updateConfig(){ 125 | $baseForm = array('token', 'welcome', 'notfound', 'dropTable'); 126 | $deluxeForm = array('appid', 'appsecret', 'access_token', 'expires_in'); 127 | $thirdPartyForm = array('thirdPartyUrl', 'thirdPartyToken', 'thirdPartySearch'); 128 | $creditForm = array('subscribe_credit'); 129 | $do = $this->request->get('do').'Form'; 130 | 131 | $settings = $this->request->from(${$do}); //动态传递表单参数 132 | foreach ($settings as $key => $value) { 133 | //if(!is_null($settings[$key])){ //判断参数是否为NULL 134 | $row['name'] = 'WCH_'.$key; 135 | $row['value'] = $value; 136 | if($this->db->fetchRow($this->select()->where('name = ?', $row['name'])->limit(1))){ 137 | $this->update($row, $this->db->sql()->where('name = ?', $row['name'])); 138 | }else{ 139 | $this->insert($row); 140 | } 141 | //} 142 | } 143 | /** 提示信息 */ 144 | $this->widget('Widget_Notice')->set(_t('设置已经保存'), 'success'); 145 | 146 | /** 转向原页 */ 147 | $this->response->goBack(); 148 | } 149 | 150 | public function action() { 151 | $this->on($this->request->is('do'))->updateConfig(); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /Widget/CustomReply.php: -------------------------------------------------------------------------------- 1 | siteUrl = Helper::options()->siteUrl; 16 | } 17 | public function getCurrentPage(){ 18 | return $this->_currentPage ? $this->_currentPage : 1; 19 | } 20 | public function select() { 21 | return $this->db->select()->from('table.wch_reply'); 22 | } 23 | public function insert(array $options) { 24 | return $this->db->query($this->db->insert('table.wch_reply')->rows($options)); 25 | } 26 | public function update(array $options, Typecho_Db_Query $condition){ 27 | return $this->db->query($condition->update('table.wch_reply')->rows($options)); 28 | } 29 | public function delete(Typecho_Db_Query $condition){ 30 | return $this->db->query($condition->delete('table.wch_reply')); 31 | } 32 | public function size(Typecho_Db_Query $condition){ 33 | return $this->db->fetchObject($condition->select(array('COUNT(table.wch_reply.rid)' => 'num'))->from('table.wch_reply'))->num; 34 | } 35 | public function execute(){ 36 | $this->parameter->setDefault('pageSize=10'); 37 | $this->_currentPage = $this->request->get('page', 1); 38 | 39 | /** 构建基础查询 */ 40 | $select = $this->db->select()->from('table.wch_reply'); 41 | 42 | /** 过滤分类 */ 43 | if (NULL != ($keywords = $this->request->keywords)) { 44 | $rids = $this->db->fetchAll($this->db->select('distinct rid')->from('table.wch_keywords')->where('name like ?', '%' . $keywords . '%')); 45 | foreach ($rids as $rid) { 46 | $select->orWhere('rid = ?', $rid['rid']); 47 | } 48 | } 49 | 50 | /** 过滤类别 */ 51 | if (NULL != ($type = $this->request->type)) { 52 | $select->where('type = ?', $type); 53 | } 54 | 55 | /** 给计算数目对象赋值,克隆对象 */ 56 | $this->_countSql = clone $select; 57 | 58 | /** 提交查询 */ 59 | $select->page($this->_currentPage, $this->parameter->pageSize)->order('table.wch_reply.rid', Typecho_Db::SORT_DESC); 60 | $this->db->fetchAll($select, array($this, 'push')); 61 | } 62 | 63 | /** 64 | * 输出分页 65 | */ 66 | public function pageNav() { 67 | $query = $this->request->makeUriByRequest('page={page}'); 68 | 69 | /** 使用盒状分页 */ 70 | $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, $this->_currentPage, $this->parameter->pageSize, $query); 71 | $nav->render('«', '»'); 72 | } 73 | /** 74 | * 生成表单 75 | * 76 | * @access public 77 | * @param string $action 表单动作 78 | * @return Typecho_Widget_Helper_Form_Element 79 | */ 80 | public function form($action = NULL) { 81 | if (isset($this->request->rid) && 'insert' != $action) { 82 | /** 更新模式 */ 83 | $custom = $this->db->fetchRow($this->select()->where('rid = ?', $this->request->rid)->limit(1)); 84 | 85 | if (!$custom) { 86 | $this->response->redirect(Helper::url('WeChatHelper/Page/CustomReply.php', $this->options->adminUrl)); 87 | } 88 | } 89 | 90 | /** 构建表格 */ 91 | $form = new Typecho_Widget_Helper_Form($this->security->getIndex('action/WeChat?customreply'), Typecho_Widget_Helper_Form::POST_METHOD); 92 | 93 | $keywords = new Typecho_Widget_Helper_Form_Element_Text('keywords', NULL, NULL, 94 | _t('关键字'), _t('多个关键字请用英文逗号分开,如:typecho,binjoo,冰剑')); 95 | $form->addInput($keywords); 96 | 97 | $typeOptions = Utils::getMsgType(); 98 | 99 | $systemSelect = ''; 108 | $typeOptions['system'] = $typeOptions['system'] . ' ' . $systemSelect; //系统消息 109 | 110 | $addonsArray = Typecho_Widget::widget('WeChatHelper_Widget_Addons')->getAddons(); 111 | if(count($addonsArray)){ 112 | $addonsSelect = ''; 121 | $typeOptions['addons'] = $typeOptions['addons'] . ' ' . $addonsSelect; 122 | }else{ 123 | unset($typeOptions['addons']); 124 | } 125 | 126 | $type = new Typecho_Widget_Helper_Form_Element_Radio('type', $typeOptions, 'text', '消息类型', NULL); 127 | $form->addInput($type->multiMode()); 128 | 129 | $content = new Typecho_Widget_Helper_Form_Element_Textarea('content', NULL, NULL, '回复内容', ' 130 | 文本消息:填写需要回复的内容;
131 | 图片消息:填写图片绝对路径即可;
132 | 系统消息:不需要填写任何内容。'); 133 | $form->addInput($content); 134 | 135 | $status = new Typecho_Widget_Helper_Form_Element_Radio('status', 136 | array('1' => '激活', '0' => '冻结'), 137 | '1', '激活状态', NULL); 138 | $form->addInput($status); 139 | 140 | $command = new Typecho_Widget_Helper_Form_Element_Hidden('command', NULL, NULL); 141 | $form->addInput($command); 142 | 143 | $param = new Typecho_Widget_Helper_Form_Element_Hidden('param', NULL, NULL); 144 | $form->addInput($param); 145 | 146 | $rid = new Typecho_Widget_Helper_Form_Element_Hidden('rid', NULL, NULL); 147 | $form->addInput($rid); 148 | 149 | $do = new Typecho_Widget_Helper_Form_Element_Hidden('do', NULL, NULL); 150 | $form->addInput($do); 151 | 152 | $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, _t('保存自定义回复')); 153 | $submit->input->setAttribute('class', 'btn primary'); 154 | $form->addItem($submit); 155 | 156 | if (isset($this->request->rid) && 'insert' != $action) { 157 | if($custom['type'] == "system"){ 158 | $content->input->setAttribute('readonly', true); 159 | } 160 | $keywords->value($custom['keywords']); 161 | $type->value($custom['type']); 162 | $command->value($custom['command']); 163 | $param->value($custom['param']); 164 | $content->value($custom['content']); 165 | $status->value($custom['status']); 166 | $rid->value($custom['rid']); 167 | $submit->value(_t('编辑自定义回复')); 168 | $do->value('update'); 169 | $_action = 'update'; 170 | } else { 171 | $submit->value(_t('增加自定义回复')); 172 | $do->value('insert'); 173 | $_action = 'insert'; 174 | } 175 | 176 | if (empty($action)) { 177 | $action = $_action; 178 | } 179 | 180 | /** 给表单增加规则 */ 181 | if ('insert' == $action || 'update' == $action) { 182 | $keywords->addRule('required', _t('关键字不能为空')); 183 | $keywords->addRule(array($this, 'keywordsExists'), _t('关键字名称已经存在')); 184 | //$type->addRule(array($this, 'typeExists'), _t('该系统消息类型已经存在')); 185 | $content->addRule('required', _t('回复内容不能为空')); 186 | //$content->addRule(array($this, 'contentExists'), _t('关键字名称已经存在')); 187 | } 188 | 189 | if ('update' == $action) { 190 | $rid->addRule('required', _t('分类主键不存在')); 191 | //$mid->addRule(array($this, 'categoryExists'), _t('分类不存在')); 192 | } 193 | 194 | return $form; 195 | } 196 | 197 | public function insertCustomReply(){ 198 | if ($this->form('insert')->validate()) { 199 | $this->response->goBack(); 200 | } 201 | 202 | /** 取出数据 */ 203 | $customReply = $this->request->from('keywords', 'type', 'command', 'param', 'content', 'status'); 204 | 205 | $customReply['created'] = time(); 206 | 207 | /** 插入数据 */ 208 | $customReply['rid'] = $this->db->query($this->insert($customReply)); 209 | $this->insertKeywords($customReply); 210 | $this->push($customReply); 211 | 212 | /** 设置高亮 */ 213 | $this->widget('Widget_Notice')->highlight('rid-customreply-'.$customReply['rid']); 214 | 215 | /** 提示信息 */ 216 | $this->widget('Widget_Notice')->set(_t('自定义回复 %s 已经被增加', $customReply['keywords']), 'success'); 217 | 218 | /** 转向原页 */ 219 | $this->response->redirect(Helper::url('WeChatHelper/Page/CustomReply.php', $this->options->adminUrl)); 220 | } 221 | 222 | public function updateCustomReply(){ 223 | if ($this->form('update')->validate()) { 224 | $this->response->goBack(); 225 | } 226 | /** 取出数据 */ 227 | $customReply = $this->request->from('keywords', 'type', 'command', 'param', 'content', 'status', 'rid'); 228 | 229 | /** 更新数据 */ 230 | $this->db->query($this->update($customReply, $this->db->sql()->where('rid = ?', $this->request->filter('int')->rid))); 231 | $this->db->query($this->db->sql()->delete('table.wch_keywords')->where('rid = ?', $customReply['rid'])); 232 | $this->insertKeywords($customReply); 233 | $this->push($customReply); 234 | 235 | /** 设置高亮 */ 236 | $this->widget('Widget_Notice')->highlight('rid-customreply-'.$customReply['rid']); 237 | 238 | /** 提示信息 */ 239 | $this->widget('Widget_Notice')->set(_t('自定义回复 %s 已经被更新', $customReply['keywords']), 'success'); 240 | 241 | /** 转向原页 */ 242 | $this->response->redirect(Helper::url('WeChatHelper/Page/CustomReply.php&page='.$this->_currentPage, $this->options->adminUrl)); 243 | } 244 | 245 | public function deleteCustomReply(){ 246 | $customreplys = $this->request->filter('int')->getArray('rid'); 247 | $deleteCount = 0; 248 | 249 | if ($customreplys && is_array($customreplys)) { 250 | foreach ($customreplys as $customreply) { 251 | if ($this->delete($this->db->sql()->where('rid = ?', $customreply))) { 252 | $this->db->query($this->db->sql()->delete('table.wch_keywords')->where('rid = ?', $customreply)); 253 | $deleteCount ++; 254 | } 255 | } 256 | } 257 | 258 | /** 提示信息 */ 259 | $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('自定义回复已经删除') : _t('没有自定义回复被删除'), 260 | $deleteCount > 0 ? 'success' : 'notice'); 261 | 262 | /** 转向原页 */ 263 | $this->response->redirect(Helper::url('WeChatHelper/Page/CustomReply.php', $this->options->adminUrl)); 264 | } 265 | 266 | public function insertKeywords($customReply){ 267 | foreach (explode(",", $customReply['keywords']) as $key => $value) { 268 | if($value){ 269 | $keyObj['name'] = $value; 270 | $keyObj['rid'] = $customReply['rid']; 271 | $this->db->query($this->db->insert('table.wch_keywords')->rows($keyObj)); 272 | } 273 | } 274 | } 275 | 276 | /** 277 | * 判断关键字是否存在 278 | */ 279 | public function keywordsExists($keywords) { 280 | foreach (explode(",", $keywords) as $key => $value) { 281 | if($value){ 282 | $select = $this->db->select()->from('table.wch_keywords')->where('name = ?', $value); 283 | if ($this->request->rid) { 284 | $select->where('rid <> ?', $this->request->rid); 285 | } 286 | $result = $this->db->fetchRow($select->limit(1)); 287 | if($result){ 288 | break; 289 | }else{ 290 | continue; 291 | } 292 | } 293 | } 294 | return $result ? false : true; 295 | } 296 | 297 | /** 298 | * 判断消息类型是否存在 299 | */ 300 | public function typeExists($type) { 301 | if($this->request->type === 'system'){ 302 | $select = $this->db->select(array('COUNT(table.wch_reply.rid)' => 'num'))->from('table.wch_reply')->where('type = ?', 'system')->where('command = ?', $this->request->command); 303 | if(!is_null($this->request->rid)){ 304 | $select->where('rid <> ?', $this->request->rid); 305 | } 306 | $result = $this->db->fetchObject($select); 307 | } 308 | return $result->num ? false : true; 309 | } 310 | public function action() { 311 | $this->security->protect(); 312 | $this->on($this->request->is('do=insert'))->insertCustomReply(); 313 | $this->on($this->request->is('do=update'))->updateCustomReply(); 314 | $this->on($this->request->is('do=delete'))->deleteCustomReply(); 315 | $this->response->redirect($this->options->adminUrl); 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /Widget/Menus.php: -------------------------------------------------------------------------------- 1 | siteUrl = Helper::options()->siteUrl; 16 | } 17 | 18 | public function select() { 19 | return $this->db->select()->from('table.wch_menus'); 20 | } 21 | public function insert(array $options) { 22 | return $this->db->query($this->db->insert('table.wch_menus')->rows($options)); 23 | } 24 | public function update(array $options, Typecho_Db_Query $condition){ 25 | return $this->db->query($condition->update('table.wch_menus')->rows($options)); 26 | } 27 | public function delete(Typecho_Db_Query $condition){ 28 | return $this->db->query($condition->delete('table.wch_menus')); 29 | } 30 | public function size(Typecho_Db_Query $condition){ 31 | return $this->db->fetchObject($condition->select(array('COUNT(table.wch_menus.uid)' => 'num'))->from('table.wch_menus'))->num; 32 | } 33 | 34 | public function execute(){ 35 | /** 构建基础查询 */ 36 | $select = $this->select()->from('table.wch_menus'); 37 | 38 | /** 给计算数目对象赋值,克隆对象 */ 39 | $this->_countSql = clone $select; 40 | 41 | /** 提交查询 */ 42 | $select->order('table.wch_menus.sort', Typecho_Db::SORT_ASC); 43 | $this->db->fetchAll($select, array($this, 'push')); 44 | } 45 | 46 | public function filter(array $value) { 47 | $value['levelVal'] = $value['level'] == 'button' ? '##' : '└──'; 48 | $value['tr'] = $value['level'] == 'button' ? 'style="background-color: #F0F0EC"' : ''; 49 | return $value; 50 | } 51 | 52 | public function push(array $value) { 53 | $value = $this->filter($value); 54 | return parent::push($value); 55 | } 56 | 57 | /** 58 | * 生成表单 59 | * 60 | * @access public 61 | * @param string $action 表单动作 62 | * @return Typecho_Widget_Helper_Form_Element 63 | */ 64 | public function form($action = NULL) { 65 | if (isset($this->request->mid) && 'insert' != $action) { 66 | /** 更新模式 */ 67 | $menu = $this->db->fetchRow($this->select()->where('mid = ?', $this->request->mid)->limit(1)); 68 | 69 | if (!$menu) { 70 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 71 | } 72 | } 73 | /** 构建表格 */ 74 | $form = new Typecho_Widget_Helper_Form($this->security->getIndex('action/WeChat?menus'), Typecho_Widget_Helper_Form::POST_METHOD); 75 | 76 | $select = $this->select()->where('table.wch_menus.parent = ?', '0')->order('table.wch_menus.order', Typecho_Db::SORT_ASC); 77 | $buttonMenus = $this->db->fetchAll($select); 78 | 79 | $parent = ''; 88 | 89 | $level = new Typecho_Widget_Helper_Form_Element_Radio('level', 90 | array('button' => _t('一级菜单'), 'sub_button' => _t('二级菜单 '.$parent)), 91 | 'button', _t('消息类型'), NULL); 92 | $form->addInput($level->multiMode()); 93 | 94 | $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, 95 | _t('标题'), _t('菜单标题,不超过16个字节。')); 96 | $form->addInput($name); 97 | 98 | $type = new Typecho_Widget_Helper_Form_Element_Radio('type', array('click' => _t('Click类型'), 'view' => _t('View类型')), 'click', _t('消息类型'), NULL); 99 | $form->addInput($type); 100 | 101 | $value = new Typecho_Widget_Helper_Form_Element_Text('value', NULL, NULL, 102 | _t('Key & URL值'), _t('Click类型:菜单KEY值,用于消息接口推送,不超过128字节;
View类型:网页链接,用户点击菜单可打开链接,不超过256字节。')); 103 | $form->addInput($value); 104 | 105 | $order = new Typecho_Widget_Helper_Form_Element_Select('order', 106 | array('1' => _t('1'), 107 | '2' => _t('2'), 108 | '3' => _t('3'), 109 | '4' => _t('4'), 110 | '5' => _t('5')), '1', _t('排序'), NULL); 111 | $form->addInput($order); 112 | 113 | $do = new Typecho_Widget_Helper_Form_Element_Hidden('do', NULL, NULL); 114 | $form->addInput($do); 115 | 116 | $mid = new Typecho_Widget_Helper_Form_Element_Hidden('mid', NULL, NULL); 117 | $form->addInput($mid); 118 | 119 | $submit = new Typecho_Widget_Helper_Form_Element_Submit(NULL, NULL, NULL); 120 | $submit->input->setAttribute('class', 'btn primary'); 121 | $form->addItem($submit); 122 | 123 | if (isset($this->request->mid) && 'insert' != $action) { 124 | $level->value($menu['level']); 125 | $name->value($menu['name']); 126 | $type->value($menu['type']); 127 | $value->value($menu['value']); 128 | $order->value($menu['order']); 129 | $mid->value($menu['mid']); 130 | $submit->value(_t('编辑菜单')); 131 | $do->value('update'); 132 | $_action = 'update'; 133 | } else { 134 | $submit->value(_t('增加菜单')); 135 | $do->value('insert'); 136 | $_action = 'insert'; 137 | } 138 | 139 | if (empty($action)) { 140 | $action = $_action; 141 | } 142 | 143 | /** 给表单增加规则 */ 144 | if ('insert' == $action || 'update' == $action) { 145 | $level->addRule(array($this, 'checkLevelNum'), _t('一级标题不能超过3个或同一一级标题下的二级标题不能超过5个。'), 'mid'); 146 | $name->addRule('required', _t('标题不能为空')); 147 | $name->addRule(array($this, 'checkMaxLength'), _t('菜单标题最多包含16个字符'), 'type'); 148 | $value->addRule(array($this, 'checkKeyOrUrl'), _t('URL格式不正确'), 'type'); 149 | $value->addRule(array($this, 'checkKeyOrUrlMaxLength'), _t('View类型最多包含128个字符,Click类型最多包含256个字符。'), 'type'); 150 | //$name->addRule('checkMaxLength', _t('菜单标题最多包含5个字符'), 5); 151 | } 152 | 153 | if ('update' == $action) { 154 | $mid->addRule('required', _t('菜单主键不存在')); 155 | //$mid->addRule(array($this, 'categoryExists'), _t('分类不存在')); 156 | } 157 | 158 | return $form; 159 | } 160 | 161 | public function checkMaxLength($name, $type){ 162 | $type = $this->request->get($type); 163 | $length = 16; 164 | if(strlen($name) > $length){ 165 | return false; 166 | }else{ 167 | return true; 168 | } 169 | } 170 | 171 | public function checkKeyOrUrl($value, $type){ 172 | $type = $this->request->get($type); 173 | if($type == 'view'){ 174 | return Typecho_Validate::url($value); 175 | }else{ 176 | return true; 177 | } 178 | } 179 | 180 | public function checkLevelNum($value, $mid){ 181 | $mid = $this->request->get($mid); 182 | $select = $this->db->sql()->select(array('COUNT(table.wch_menus.mid)' => 'num'))->from('table.wch_menus')->where('level = ?', $value); 183 | if($value == 'button'){ 184 | if($mid){ 185 | $select->where('mid <> ?', $mid); 186 | } 187 | $num = $this->db->fetchObject($select)->num; 188 | if($num>=3){ 189 | return false; 190 | }else{ 191 | return true; 192 | } 193 | }else if($value == 'sub_button'){ 194 | $parent = $this->request->get('parent'); 195 | if($parent){ 196 | $select->where('parent = ?', $parent); 197 | } 198 | if($mid){ 199 | $select->where('mid <> ?', $mid); 200 | } 201 | $num = $this->db->fetchObject($select)->num; 202 | if($num>=5){ 203 | return false; 204 | }else{ 205 | return true; 206 | } 207 | } 208 | } 209 | 210 | public function checkKeyOrUrlMaxLength($value, $type){ 211 | $type = $this->request->get($type); 212 | $length = $type == 'click' ? 256 : 128; 213 | if(strlen($value) > $length){ 214 | return false; 215 | }else{ 216 | return true; 217 | } 218 | } 219 | 220 | public function getParentOrder($menu){ 221 | if($menu['level'] == 'sub_button'){ 222 | $select = $this->db->sql()->select(array('table.wch_menus.order' => 'order'))->from('table.wch_menus')->where('mid = ?', $menu['parent']); 223 | $order = $this->db->fetchObject($select)->order; 224 | $menu['sort'] = ($order * 10) + $menu['order']; 225 | }else{ 226 | $menu['sort'] = $menu['order'] * 10; 227 | $menu['parent'] = '0'; 228 | } 229 | return $menu; 230 | } 231 | 232 | /** 233 | * 分类排序 234 | * 235 | * @access public 236 | * @return void 237 | */ 238 | public function orderMenu() { 239 | $menus = $this->request->filter('int')->getArray('mid'); 240 | $levels = $this->request->getArray('level'); 241 | if ($menus) { 242 | $parent = 0; 243 | foreach ($menus as $sort => $mid) { 244 | $param = array('order' => $sort + 1); 245 | if($levels[$sort] == 'button'){ 246 | $parent = $mid; 247 | $param['parent'] = '0'; 248 | }else{ 249 | $param['parent'] = $parent; 250 | } 251 | $this->update($param, $this->db->sql()->where('mid = ?', $mid)); 252 | } 253 | } 254 | 255 | if (!$this->request->isAjax()) { 256 | /** 转向原页 */ 257 | $this->response->redirect(Typecho_Common::url('manage-categories.php', $this->options->adminUrl)); 258 | } else { 259 | $this->response->throwJson(array('success' => 1, 'message' => _t('分类排序已经完成'))); 260 | } 261 | } 262 | 263 | public function insertMenu() { 264 | if ($this->form('insert')->validate()) { 265 | $this->response->goBack(); 266 | } 267 | /** 取出数据 */ 268 | $menu = $this->request->from('level', 'name', 'type', 'value', 'parent', 'order'); 269 | $menu = $this->getParentOrder($menu); 270 | $menu['created'] = time(); 271 | 272 | /** 插入数据 */ 273 | $menu['mid'] = $this->db->query($this->insert($menu)); 274 | $this->push($menu); 275 | 276 | $this->widget('Widget_Notice')->highlight('menus-mid-'.$menu['mid']); 277 | $this->widget('Widget_Notice')->set(_t('自定义菜单添加成功'), 'success'); 278 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 279 | } 280 | 281 | public function updateMenu() { 282 | if ($this->form('insert')->validate()) { 283 | $this->response->goBack(); 284 | } 285 | /** 取出数据 */ 286 | $menu = $this->request->from('level', 'name', 'type', 'value', 'parent', 'order', 'mid'); 287 | $menu = $this->getParentOrder($menu); 288 | 289 | /** 插入数据 */ 290 | $this->db->query($this->update($menu, $this->db->sql()->where('mid = ?', $this->request->filter('int')->mid))); 291 | if($menu['level'] == 'button'){ 292 | $this->db->query($this->db->sql()->update('table.wch_menus')->where('parent = ?', $menu['mid'])->expression('sort', ($menu['order'] * 10) . ' + `order` ')); 293 | } 294 | $this->push($menu); 295 | 296 | $this->widget('Widget_Notice')->highlight('menus-mid-'.$menu['mid']); 297 | $this->widget('Widget_Notice')->set(_t('自定义菜单修改成功'), 'success'); 298 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 299 | } 300 | 301 | public function deleteMenu() { 302 | $menus = $this->request->filter('int')->getArray('mid'); 303 | $deleteCount = 0; 304 | 305 | if ($menus && is_array($menus)) { 306 | foreach ($menus as $menu) { 307 | if ($this->delete($this->db->sql()->where('mid = ?', $menu)->orWhere('parent = ?', $menu))) { 308 | $deleteCount ++; 309 | } 310 | } 311 | } 312 | 313 | /** 提示信息 */ 314 | $this->widget('Widget_Notice')->set($deleteCount > 0 ? _t('自定义菜单已经删除') : _t('没有自定义菜单被删除'), 315 | $deleteCount > 0 ? 'success' : 'notice'); 316 | 317 | /** 转向原页 */ 318 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 319 | } 320 | 321 | public function createMenu(){ 322 | $accessToken = Utils::getAccessToken(); 323 | if(!$accessToken){ 324 | $this->widget('Widget_Notice')->set('获取Access Token异常!', 'error'); 325 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 326 | } 327 | $create['button'] = array(); 328 | $select = $this->select()->where('level = ?', 'button')->order('table.wch_menus.order', Typecho_Db::SORT_ASC); 329 | $buttons = $this->db->fetchAll($select); 330 | if (count($buttons) > 3 || !count($buttons)) { 331 | $this->widget('Widget_Notice')->set(_t('错误:一级菜单没有找到或超过三个.'), 'error'); 332 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 333 | } 334 | foreach ($buttons as $row) { 335 | $button = array(); 336 | $select = ""; 337 | $select = $this->select()->where('level = ?', 'sub_button')->where('parent = ?', $row['mid'])->order('table.wch_menus.order', Typecho_Db::SORT_ASC); 338 | $subButtons = $this->db->fetchAll($select); 339 | if (!count($subButtons)) { //没有二级菜单 340 | $button['type'] = urlencode($row['type']); 341 | $button['name'] = urlencode($row['name']); 342 | $button[$row['type'] == 'view' ? 'url' : 'key'] = urlencode($row['value']); 343 | }else{ 344 | $button['name'] = urlencode($row['name']); 345 | $tmp = array(); 346 | foreach ($subButtons as $row) { 347 | $subButton = array(); 348 | $subButton['type'] = urlencode($row['type']); 349 | $subButton['name'] = urlencode($row['name']); 350 | $subButton[$row['type'] == 'view' ? 'url' : 'key'] = urlencode($row['value']); 351 | array_push($tmp, $subButton); 352 | } 353 | $button['sub_button'] = $tmp; 354 | } 355 | array_push($create['button'], $button); 356 | } 357 | 358 | $json = json_encode($create); 359 | 360 | try { 361 | $client = Typecho_Http_Client::get(); 362 | $params = array('access_token' => $accessToken); 363 | $response = $client->setQuery($params)->setData(urldecode($json))->send(Utils::MENU_CREATE_URL); 364 | } catch (Exception $e) { 365 | $this->widget('Widget_Notice')->set(_t('对不起,创建自定义菜单失败,请重试!'), 'error'); 366 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 367 | } 368 | 369 | $result = json_decode($response); 370 | if($result->errcode){ 371 | $this->widget('Widget_Notice')->set(_t('对不起,创建自定义菜单失败,错误原因:'.$result->errmsg), 'notice'); 372 | }else{ 373 | $this->widget('Widget_Notice')->set(_t('恭喜您,创建自定义菜单成功!'), 'success'); 374 | } 375 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 376 | } 377 | 378 | public function removeMenu(){ 379 | $accessToken = Utils::getAccessToken(); 380 | if(!$accessToken){ 381 | $this->widget('Widget_Notice')->set('获取Access Token异常!', 'error'); 382 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 383 | } 384 | 385 | try { 386 | $client = Typecho_Http_Client::get(); 387 | $params = array('access_token' => $accessToken); 388 | $response = $client->setQuery($params)->send(Utils::MENU_REMOVE_URL); 389 | } catch (Exception $e) { 390 | $this->widget('Widget_Notice')->set(_t('对不起,删除自定义菜单失败,请重试!'), 'error'); 391 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 392 | } 393 | 394 | $result = json_decode($response); 395 | if($result->errcode){ 396 | $this->widget('Widget_Notice')->set(_t('对不起,删除自定义菜单失败,错误原因:'.$result->errmsg), 'notice'); 397 | }else{ 398 | $this->widget('Widget_Notice')->set(_t('恭喜您,删除自定义菜单成功!'), 'success'); 399 | } 400 | $this->response->redirect(Helper::url('WeChatHelper/Page/Menus.php', $this->options->adminUrl)); 401 | } 402 | 403 | public function action() { 404 | $this->security->protect(); 405 | $this->on($this->request->is('do=insert'))->insertMenu(); 406 | $this->on($this->request->is('do=update'))->updateMenu(); 407 | $this->on($this->request->is('do=delete'))->deleteMenu(); 408 | $this->on($this->request->is('do=order'))->orderMenu(); 409 | $this->on($this->request->is('do=create'))->createMenu(); 410 | $this->on($this->request->is('do=remove'))->removeMenu(); 411 | $this->response->redirect($this->options->adminUrl); 412 | } 413 | } 414 | -------------------------------------------------------------------------------- /Widget/Users.php: -------------------------------------------------------------------------------- 1 | siteUrl = Helper::options()->siteUrl; 16 | } 17 | public function getCurrentPage(){ 18 | return $this->_currentPage ? $this->_currentPage : 1; 19 | } 20 | public function select() { 21 | return $this->db->select()->from('table.wch_users'); 22 | } 23 | public function insert(array $options) { 24 | return $this->db->query($this->db->insert('table.wch_users')->rows($options)); 25 | } 26 | public function update(array $options, Typecho_Db_Query $condition){ 27 | return $this->db->query($condition->update('table.wch_users')->rows($options)); 28 | } 29 | public function delete(Typecho_Db_Query $condition){ 30 | return $this->db->query($condition->delete('table.wch_users')); 31 | } 32 | public function size(Typecho_Db_Query $condition){ 33 | return $this->db->fetchObject($condition->select(array('COUNT(table.wch_users.uid)' => 'num'))->from('table.wch_users'))->num; 34 | } 35 | 36 | public function execute(){ 37 | $this->parameter->setDefault('pageSize=10'); 38 | $this->_currentPage = $this->request->get('page', 1); 39 | 40 | /** 构建基础查询 */ 41 | $select = $this->db->select()->from('table.wch_users')->where('table.wch_users.status = ?', '1'); 42 | 43 | /** 给计算数目对象赋值,克隆对象 */ 44 | $this->_countSql = clone $select; 45 | 46 | /** 提交查询 */ 47 | $select->page($this->_currentPage, $this->parameter->pageSize)->order('table.wch_users.uid', Typecho_Db::SORT_DESC); 48 | $this->db->fetchAll($select, array($this, 'push')); 49 | } 50 | 51 | public function filter(array $value) { 52 | $date = new Typecho_Date($value['subscribe_time']); 53 | $value['subscribeFormat'] = $date->format('Y-m-d H:i:s'); 54 | 55 | $value['bindVal'] = $value['bind'] ? '是' : '否'; 56 | 57 | switch ($value['sex']) { 58 | case '1': 59 | $value['sexVal'] = '男'; 60 | break; 61 | case '2': 62 | $value['sexVal'] = '女'; 63 | break; 64 | default: 65 | $value['sexVal'] = '不明'; 66 | break; 67 | } 68 | 69 | $value['address'] = $value['country'] . ',' . $value['province'] . ',' . $value['city']; 70 | if($value['address'] == ',,'){ 71 | $value['address'] = ''; 72 | } 73 | 74 | if($value['headimgurl']){ 75 | $value['headimgurl0'] = $value['headimgurl'].'0'; 76 | $value['headimgurl46'] = $value['headimgurl'].'46'; 77 | $value['headimgurl64'] = $value['headimgurl'].'64'; 78 | $value['headimgurl96'] = $value['headimgurl'].'96'; 79 | $value['headimgurl132'] = $value['headimgurl'].'132'; 80 | }else{ 81 | $value['headimgurl'] = Helper::options()->pluginUrl .'/WeChatHelper/Images/UserHeadDefault.jpg'; 82 | $value['headimgurl0'] = $value['headimgurl']; 83 | $value['headimgurl46'] = $value['headimgurl']; 84 | $value['headimgurl64'] = $value['headimgurl']; 85 | $value['headimgurl96'] = $value['headimgurl']; 86 | $value['headimgurl132'] = $value['headimgurl']; 87 | } 88 | 89 | $date = new Typecho_Date($value['created']); 90 | $value['createdFormat'] = $date->format('Y-m-d H:i:s'); 91 | return $value; 92 | } 93 | 94 | public function push(array $value) { 95 | $value = $this->filter($value); 96 | return parent::push($value); 97 | } 98 | 99 | /** 100 | * 输出分页 101 | */ 102 | public function pageNav() { 103 | $query = $this->request->makeUriByRequest('page={page}'); 104 | 105 | /** 使用盒状分页 */ 106 | $nav = new Typecho_Widget_Helper_PageNavigator_Box(false === $this->_total ? $this->_total = $this->size($this->_countSql) : $this->_total, $this->_currentPage, $this->parameter->pageSize, $query); 107 | $nav->render('«', '»'); 108 | } 109 | 110 | /** 111 | * 生成表单 112 | * 113 | * @access public 114 | * @param string $action 表单动作 115 | * @return Typecho_Widget_Helper_Form_Element 116 | */ 117 | public function form($action = NULL) { 118 | } 119 | 120 | /** 121 | * 关注事件 122 | */ 123 | public function subscribe($postObj){ 124 | //$user = $this->db->fetchRow($this->select()->where('openid = ?', $postObj->FromUserName)->limit(1)); 125 | $accessToken = Utils::getAccessToken(); 126 | if (!$this->openIdExists((String) $postObj->FromUserName)) { 127 | if($accessToken){ 128 | $result = $this->apiGetUser((String) $postObj->FromUserName, $accessToken); 129 | $result = json_decode($result); 130 | $user = (array) $result; 131 | $user['created'] = time(); 132 | unset($user['subscribe']); 133 | }else{ 134 | $user = array('openid' => $postObj->FromUserName, 'subscribe_time' => time(), 'created' => time()); 135 | } 136 | $user['credits'] = isset($this->options->WCH_subscribe_credit) ? $this->options->WCH_subscribe_credit : '0'; 137 | $user['uid'] = $this->insert($user); 138 | }else{ 139 | $user['status'] = '1'; 140 | $user['uid'] = $this->update($user, $this->db->sql()->where('openid = ?', (String) $postObj->FromUserName)); 141 | } 142 | } 143 | 144 | /** 145 | * 取消关注事件 146 | */ 147 | public function unsubscribe($postObj){ 148 | if ($this->openIdExists((String) $postObj->FromUserName)) { 149 | $user['status'] = '0'; 150 | $user['uid'] = $this->update($user, $this->db->sql()->where('openid = ?', (String) $postObj->FromUserName)); 151 | } 152 | } 153 | 154 | /** 155 | * 判断OpenId是否存在 156 | */ 157 | public function openIdExists($openid){ 158 | $select = $this->select()->where('openid = ?', $openid)->limit(1); 159 | return $this->db->fetchRow($select); 160 | } 161 | 162 | /** 163 | * 同步微信用户 164 | */ 165 | public function syncUserList(){ 166 | $accessToken = Utils::getAccessToken(); 167 | if(!$accessToken){ 168 | $this->widget('Widget_Notice')->set(_t('对不起,更新微信关注者数据失败,请重试!'), 'error'); 169 | $this->response->redirect(Helper::url('WeChatHelper/Page/Users.php&page='.$this->_currentPage, $this->options->adminUrl)); 170 | } 171 | $client = Typecho_Http_Client::get(); 172 | $params = array('access_token' => $accessToken); 173 | $response = $client->setQuery($params)->send('https://api.weixin.qq.com/cgi-bin/user/get'); 174 | $response = json_decode($response); 175 | 176 | foreach ($response->data->openid as $val) { 177 | $user = array(); 178 | /* 179 | $user = array(); 180 | $client = Typecho_Http_Client::get(); 181 | $params['openid'] = $val; 182 | $result = $client->setQuery($params)->send('https://api.weixin.qq.com/cgi-bin/user/info'); 183 | $result = json_decode($result); 184 | print_r($result); 185 | $user['openid'] = $result->openid; 186 | $user['nickname'] = $result->nickname; 187 | $user['sex'] = $result->sex; 188 | $user['language'] = $result->language; 189 | $user['city'] = $result->city; 190 | $user['province'] = $result->province; 191 | $user['country'] = $result->country; 192 | $user['headimgurl'] = $result->headimgurl; 193 | $user['subscribe_time'] = $result->subscribe_time; 194 | $user['synctime'] = time(); 195 | */ 196 | $exists = $this->openIdExists($val); 197 | if($exists){ 198 | $user['status'] = '1'; 199 | $user['uid'] = $this->update($user, $this->db->sql()->where('openid = ?', $val)); 200 | }else{ 201 | $user['openid'] = $val; 202 | $user['created'] = time(); 203 | $user['uid'] = $this->insert($user); 204 | } 205 | } 206 | 207 | $this->widget('Widget_Notice')->set(_t('恭喜您,同步微信关注者列表成功!'), 'success'); 208 | $this->response->redirect(Helper::url('WeChatHelper/Page/Users.php&page='.$this->_currentPage, $this->options->adminUrl)); 209 | } 210 | 211 | /** 212 | * 同步微信用户信息 213 | */ 214 | public function syncUserInfo(){ 215 | $uid = $this->request->get('uid'); 216 | $user = $this->db->fetchRow($this->select()->where('uid = ?', $uid)->limit(1)); 217 | 218 | $accessToken = Utils::getAccessToken(); 219 | $client = Typecho_Http_Client::get(); 220 | $params = array('access_token' => $accessToken, 'openid' => $user['openid']); 221 | try { 222 | $result = $client->setQuery($params)->send('https://api.weixin.qq.com/cgi-bin/user/info'); 223 | } catch (Exception $e) { 224 | $this->widget('Widget_Notice')->set(_t('对不起,更新微信用户信息失败,请重试!'), 'error'); 225 | $this->response->redirect(Helper::url('WeChatHelper/Page/Users.php&page='.$this->_currentPage, $this->options->adminUrl)); 226 | } 227 | $result = json_decode($result); 228 | 229 | if($result->subscribe){ 230 | $user['status'] = '1'; 231 | }else{ 232 | $user['status'] = '0'; 233 | } 234 | $user['openid'] = $result->openid; 235 | $user['nickname'] = $result->nickname; 236 | $user['sex'] = $result->sex; 237 | $user['language'] = $result->language; 238 | $user['city'] = $result->city; 239 | $user['province'] = $result->province; 240 | $user['country'] = $result->country; 241 | $user['headimgurl'] = $result->headimgurl; 242 | $user['subscribe_time'] = $result->subscribe_time; 243 | $user['synctime'] = time(); 244 | 245 | $this->update($user, $this->db->sql()->where('uid = ?', $user['uid'])); 246 | 247 | $this->widget('Widget_Notice')->highlight('users-uid-'.$user['uid']); 248 | $this->widget('Widget_Notice')->set(_t('微信用户 OpenID %s 更新成功!', $user['openid']), 'success'); 249 | $this->response->redirect(Helper::url('WeChatHelper/Page/Users.php&page='.$this->_currentPage, $this->options->adminUrl)); 250 | } 251 | 252 | public function apiGetUser($openid, $accessToken = NULL){ 253 | if(!$accessToken){ 254 | $accessToken = Utils::getAccessToken(); 255 | } 256 | if($accessToken){ 257 | $client = Typecho_Http_Client::get(); 258 | $params = array('access_token' => $accessToken, 'openid' => $openid); 259 | $result = $client->setQuery($params)->send('https://api.weixin.qq.com/cgi-bin/user/info'); 260 | }else{ 261 | throw new Typecho_Plugin_Exception(_t('对不起,请求AccessToken出现异常。')); 262 | } 263 | return $result; 264 | } 265 | 266 | public function action() { 267 | $this->security->protect(); 268 | $this->on($this->request->is('do=syncList'))->syncUserList(); 269 | $this->on($this->request->is('do=syncInfo'))->syncUserInfo(); 270 | $this->response->redirect($this->options->adminUrl); 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /Widget/Utils.php: -------------------------------------------------------------------------------- 1 | '哟,客官,您来啦!'.chr(10).'发送\'h\'让小的给您介绍一下!', 8 | 'notfound' => '对不起,我完全不明白你在说什么!' 9 | ); 10 | return $tmp[$msg]; 11 | } 12 | public static function getMsgType($type = NULL){ 13 | $result = array('text' => '文本消息', 14 | //'image' => '图片消息', 15 | 'system' => '系统消息', 16 | 'addons' => '插件扩展'); 17 | if($type){ 18 | return $result[$type]; 19 | }else{ 20 | return $result; 21 | } 22 | } 23 | 24 | public static function getSystemMsg(){ 25 | $result = array('sys_random' => '随机日志', 26 | 'sys_recent' => '最新日志', 27 | 'sys_hot_comment' => '热评日志'); 28 | return $result; 29 | } 30 | 31 | public static function getAccessToken(){ 32 | $db = Typecho_Db::get(); 33 | $options = Typecho_Widget::widget('Widget_Options'); 34 | if(isset($options->WCH_appid) && isset($options->WCH_appsecret)){ 35 | if(isset($options->WCH_access_token) && isset($options->WCH_expires_in) && $options->WCH_expires_in > time()){ 36 | return $options->WCH_access_token; 37 | }else{ 38 | $client = Typecho_Http_Client::get(); 39 | $params = array('grant_type' => 'client_credential', 40 | 'appid' => $options->WCH_appid, 'secret' => $options->WCH_appsecret); 41 | $response = $client->setQuery($params)->send('https://api.weixin.qq.com/cgi-bin/token'); 42 | $response = json_decode($response); 43 | if(isset($response->errcode)){ 44 | //throw new Typecho_Plugin_Exception(_t('对不起,请求错误。ErrCode:'.$response->errcode.' - ErrMsg:'.$response->errmsg)); 45 | return NULL; 46 | }else{ 47 | $db->query($db->update('table.options')->rows(array('value' => $response->access_token))->where('name = ?', 'WeChatHelper_access_token')); 48 | $db->query($db->update('table.options')->rows(array('value' => time() + $response->expires_in))->where('name = ?', 'WeChatHelper_expires_in')); 49 | return $response->access_token; 50 | } 51 | } 52 | }else{ 53 | //throw new Typecho_Plugin_Exception(_t('对不起, 请先在高级功能中填写正确的APP ID和APP Secret。')); 54 | return NULL; 55 | } 56 | } 57 | } 58 | 59 | class MessageTemplate { 60 | const TEXT = 'text'; //文本 61 | const IMAGE = 'image'; //图片 62 | const VOICE = 'voice'; //语音 63 | const VIDEO = 'video'; //视频 64 | const MUSIC = 'music'; //音乐 65 | const NEWS = 'news'; //图文 66 | const THIRD = 'third'; //第三方 67 | private $toUserName; 68 | private $fromUserName; 69 | /** 70 | * 消息时间 71 | */ 72 | private $createTime; 73 | /** 74 | * 消息类型 75 | */ 76 | private $msgType; 77 | /** 78 | * 最终输出内容 79 | */ 80 | private $result; 81 | /** 82 | * 设置消息内容 83 | */ 84 | private $content; 85 | /** 86 | * 87 | */ 88 | private $item = array(); 89 | private $sendContent; 90 | private $_textTpl; 91 | private $_newsTpl; 92 | private $_itemTpl; 93 | 94 | public function __construct($postObj) { 95 | $this->toUserName = $postObj->ToUserName; 96 | $this->fromUserName = $postObj->FromUserName; 97 | $this->createTime = time(); 98 | $this->_textTpl = "%s0"; 99 | $this->_newsTpl = "%s%s%s0"; 100 | $this->_itemTpl = "<![CDATA[%s]]>"; 101 | } 102 | /** 103 | * 设置直接发送的消息内容,适用于第三方平台 104 | */ 105 | public function setSendContent($sendContent){ 106 | $this->sendContent = $sendContent; 107 | return $this; 108 | } 109 | /** 110 | * 设置消息类型 111 | */ 112 | public function setMsgType($msgType){ 113 | $this->msgType = $msgType; 114 | return $this; 115 | } 116 | /** 117 | * 设置文本内容 118 | */ 119 | public function setText($content) { 120 | $this->content = $content; 121 | return $this; 122 | } 123 | /** 124 | * 组合发送消息 125 | */ 126 | public function addItem($item){ 127 | array_push($this->item, $item); 128 | } 129 | public function send(){ 130 | switch ($this->msgType) { 131 | case MessageTemplate::TEXT: 132 | $this->result = sprintf($this->_textTpl, $this->fromUserName, $this->toUserName, $this->createTime, $this->content); 133 | break; 134 | case MessageTemplate::THIRD: 135 | $this->result = $this->sendContent; 136 | break; 137 | case MessageTemplate::IMAGE: 138 | $this->result = '图片类型'; 139 | break; 140 | case MessageTemplate::NEWS: 141 | foreach ($this->item as $key => $value) { 142 | $this->result .= sprintf($this->_itemTpl, $value['title'], $value['description'], $value['picurl'], $value['url']); 143 | } 144 | $this->result = sprintf($this->_newsTpl, $this->fromUserName, $this->toUserName, $this->createTime, count($this->item), $this->result); 145 | break; 146 | default: 147 | $this->result = 'error'; 148 | } 149 | echo $this->result; 150 | } 151 | } 152 | ?> -------------------------------------------------------------------------------- /Widget/WeChat.php: -------------------------------------------------------------------------------- 1 | postObj->Event == "subscribe"){ 27 | $info = Typecho_Widget::widget('WeChatHelper_Widget_Users')->subscribe($this->postObj); 28 | $this->result->setText(isset($this->options->WCH_welcome) ? $this->options->WCH_welcome : '')->setMsgType(MessageTemplate::TEXT)->send(); 29 | }else if($this->postObj->Event == "unsubscribe"){ 30 | $info = Typecho_Widget::widget('WeChatHelper_Widget_Users')->unsubscribe($this->postObj); 31 | } 32 | } 33 | /** 34 | * 文本消息 35 | */ 36 | public function isText(){ 37 | $val = $this->postObj->Content; 38 | $params = $this->isParam(); 39 | if($params){ 40 | $val = $params['cmd']; 41 | } 42 | 43 | $select = $this->db->select()->from('table.wch_reply')->join('table.wch_keywords', 'table.wch_keywords.rid = table.wch_reply.rid', Typecho_Db::LEFT_JOIN)->where('table.wch_keywords.name = ?', $val)->where('table.wch_reply.status = ?', 1)->limit(1); 44 | $custom = $this->db->fetchObject($select); 45 | if(isset($custom->content)){ //正常文本处理 46 | if($custom->type === 'text'){ 47 | $this->result->setText($custom->content)->setMsgType(MessageTemplate::TEXT)->send(); 48 | }else if($custom->type === 'image'){ 49 | $this->result->setText('助手暂时还不支持图片回复!')->setMsgType(MessageTemplate::TEXT)->send(); 50 | }else if($custom->type === 'system'){ 51 | $this->blogPost($custom->command); 52 | }else if($custom->type === 'addons'){ 53 | $this->addonsAction($custom->command, $this->postObj, $params); 54 | } 55 | }else if(isset($this->options->WCH_thirdPartySearch) && $this->options->WCH_thirdPartyUrl && $this->options->WCH_thirdPartyToken && $this->options->WCH_thirdPartySearch) { //第三方处理 56 | $this->thirdParty(); 57 | }else{ 58 | $this->result->setText(isset($this->options->WCH_notfound) ? $this->options->WCH_notfound : '完全不明白你在说什么!')->setMsgType(MessageTemplate::TEXT)->send(); 59 | } 60 | } 61 | /** 62 | * 图片消息 63 | */ 64 | public function isImage(){ 65 | $this->result->setText('助手暂时还不支持图片消息!')->setMsgType(MessageTemplate::TEXT)->send(); 66 | } 67 | /** 68 | * 语音消息 69 | */ 70 | public function isVoice(){ 71 | $this->result->setText('助手暂时还不支持语音消息!')->setMsgType(MessageTemplate::TEXT)->send(); 72 | } 73 | /** 74 | * 视频消息 75 | */ 76 | public function isVideo(){ 77 | $this->result->setText('助手暂时还不支持视频消息!')->setMsgType(MessageTemplate::TEXT)->send(); 78 | } 79 | /** 80 | * 地理位置消息 81 | */ 82 | public function isLocation(){ 83 | $this->result->setText('助手暂时还不支持地理位置消息!')->setMsgType(MessageTemplate::TEXT)->send(); 84 | } 85 | /** 86 | * 链接消息 87 | */ 88 | public function isLink(){ 89 | $this->result->setText('助手暂时还不支持链接消息!')->setMsgType(MessageTemplate::TEXT)->send(); 90 | } 91 | 92 | /** 93 | * 是否带有参数 94 | */ 95 | public function isParam(){ 96 | $select = $this->db->select()->from('table.wch_reply')->join('table.wch_keywords', 'table.wch_keywords.rid = table.wch_reply.rid', Typecho_Db::LEFT_JOIN)->where('table.wch_reply.type = ?', 'addons')->where('table.wch_reply.status = ?', 1); 97 | $allAddons = $this->db->fetchAll($select); 98 | $result = NULL; 99 | foreach ($allAddons as $row) { 100 | $len = Typecho_Common::strLen($row['name']); 101 | $cmd = Typecho_Common::substr($this->postObj->Content, 0, $len, ''); 102 | if(Typecho_Common::strLen($this->postObj->Content) > $len && $cmd === $row['name'] && $row['param']){ 103 | $result['value'] = $this->postObj->Content; 104 | $result['cmd'] = $cmd; 105 | $result['param'] = Typecho_Common::substr($this->postObj->Content, $len, Typecho_Common::strLen($this->postObj->Content, '')); 106 | break; 107 | } 108 | } 109 | return $result; 110 | } 111 | 112 | /** 113 | * 第三方平台 114 | */ 115 | public function thirdParty(){ 116 | $postStr = file_get_contents("php://input"); 117 | $params['signature'] = $this->options->WCH_thirdPartyToken; 118 | $params['timestamp'] = time(); 119 | $params['nonce'] = rand(100000000, 999999999); 120 | 121 | $client = Typecho_Http_Client::get(); 122 | $response = $client->setHeader('Content-Type', 'text/xml') 123 | ->setHeader('User-Agent', $this->useragent) 124 | ->setQuery($params) 125 | ->setData($postStr) 126 | ->send($this->options->WCH_thirdPartyUrl); 127 | $this->result->setSendContent($response)->setMsgType(MessageTemplate::THIRD)->send(); 128 | } 129 | 130 | /** 131 | * 博客日志数据 132 | */ 133 | public function blogPost($action){ 134 | $result = $this->$action(); 135 | foreach ($result as $row) { 136 | $row = Typecho_Widget::widget('Widget_Abstract_Contents')->filter($row); 137 | $item['title'] = $row['title']; 138 | $item['description'] = Typecho_Common::subStr(str_replace("\n", '', trim(strip_tags($row['text']))), 0, 100, '...'); 139 | //$item['description'] = Typecho_Common::subStr(trim(strip_tags($this->excerpt)), 0, 100, '...'); 140 | //$item['picurl'] = 'https://www.google.com/images/srpr/logo11w.png'; 141 | 142 | $img = array(); 143 | $image = ''; 144 | if(0 === strpos($row['text'], '')){ 145 | echo 'yes'; 146 | }else{ 147 | preg_match('/("|\'|\(|(:\s)|=)(http:\/\/(.*?)\.(jpg|gif|png|bmp))/i', $row['text'], $img); 148 | if(count($img)){ 149 | preg_match('/^(.*?)h/is', $img[0], $prefix); 150 | if(!isset($prefix[1])) $prefix[1] = ''; 151 | $image = str_replace($prefix[1], '', $img[0]); 152 | } 153 | } 154 | 155 | //print_r($image); 156 | 157 | $item['picurl'] = $image; 158 | $item['url'] = $row['permalink']; 159 | $this->result->addItem($item); 160 | } 161 | $this->result->setMsgType(MessageTemplate::NEWS)->send(); 162 | } 163 | 164 | private function sysGeneralSql(){ 165 | $sql = $this->db->select()->from('table.contents') 166 | ->where('table.contents.status = ?', 'publish') 167 | ->where('table.contents.created < ?', $this->options->gmtTime) 168 | ->where('table.contents.type = ?', 'post') 169 | ->where('table.contents.password IS NULL'); 170 | return $sql; 171 | } 172 | 173 | /** 174 | * 最新日志 175 | */ 176 | private function sys_recent(){ 177 | $sql = $this->sysGeneralSql()->order('table.contents.created', Typecho_Db::SORT_DESC)->limit(5); 178 | $result = $this->db->fetchAll($sql); 179 | return $result; 180 | } 181 | 182 | /** 183 | * 随机日志 184 | */ 185 | private function sys_random(){ 186 | $sql = $this->sysGeneralSql()->limit(5)->order('RAND()'); 187 | $result = $this->db->fetchAll($sql); 188 | return $result; 189 | } 190 | 191 | /** 192 | * 热评日志 193 | */ 194 | private function sys_hot_comment(){ 195 | $sql = $this->sysGeneralSql()->order('table.contents.commentsNum', Typecho_Db::SORT_DESC)->limit(5); 196 | $result = $this->db->fetchAll($sql); 197 | return $result; 198 | } 199 | 200 | public function addonsAction($action, $postObj, $params = NULL){ 201 | $file = __TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_PLUGIN_DIR__ . '/WeChatHelper/Addons/'.$action.'/Addon.php'; 202 | include_once $file; 203 | $info = Typecho_Widget::widget('WeChatHelper_Widget_Addons')->parseInfo($file); 204 | $class = 'Addons'.$info['package']; 205 | $addons = new $class($this->result, $postObj, $params); 206 | $addons->execute(); 207 | } 208 | 209 | public function action() { 210 | $postStr = file_get_contents("php://input");//$this->request->get("HTTP_RAW_POST_DATA"); 211 | if (!empty($postStr)){ 212 | $this->response->setContentType("text/xml"); 213 | $this->postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 214 | $this->result = new MessageTemplate($this->postObj); 215 | $exe = 'is'.ucwords($this->postObj->MsgType); 216 | if(method_exists($this, $exe)){ 217 | $this->$exe(); 218 | } 219 | } 220 | } 221 | } 222 | --------------------------------------------------------------------------------