wangtengyu
2018-11-28 b5d693294fc71eaf5c758fdaa0f215c0cc55ee6a
commit | author | age
dba282 1 <?php
B 2 /**
3  * [WeEngine System] Copyright (c) 2014 WE7.CC
4  * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details.
5  */
6 define('IN_API', true);
7 require_once './framework/bootstrap.inc.php';
8 load()->model('reply');
9 load()->model('attachment');
10
11 load()->app('common');
12 load()->classs('wesession');
13 $hash = $_GPC['hash'];
14 if(!empty($hash)) {
15     $id = pdo_fetchcolumn("SELECT acid FROM " . tablename('account') . " WHERE hash = :hash", array(':hash' => $hash));
16 }
17 if(!empty($_GPC['appid'])) {
18     $appid = ltrim($_GPC['appid'], '/');
19     if ($appid == 'wx570bc396a51b8ff8') {
20         $_W['account'] = array(
21             'type' => '3',
22             'key' => 'wx570bc396a51b8ff8',
23             'level' => 4,
24             'token' => 'platformtestaccount'
25         );
26     } else {
27         $id = pdo_fetchcolumn("SELECT acid FROM " . tablename('account_wechats') . " WHERE `key` = :appid", array(':appid' => $appid));
28     }
29 }
30 if(empty($id)) {
31     $id = intval($_GPC['id']);
32 }
33 if (!empty($id)) {
34     $uniacid = pdo_getcolumn('account', array('acid' => $id), 'uniacid');
35     $_W['account'] = uni_fetch($uniacid);
36 }
37 if(empty($_W['account'])) {
38     exit('initial error hash or id');
39 }
40 if(empty($_W['account']['token'])) {
41     exit('initial missing token');
42 }
43 $_W['debug'] = intval($_GPC['debug']);
44 $_W['acid'] = $_W['account']['acid'];
45 $_W['uniacid'] = $_W['account']['uniacid'];
46 $_W['uniaccount'] = uni_fetch($_W['uniacid']);
47 $_W['account']['groupid'] = $_W['uniaccount']['groupid'];
48 $_W['account']['qrcode'] = $_W['attachurl'].'qrcode_'.$_W['acid'].'.jpg?time='.$_W['timestamp'];
49 $_W['account']['avatar'] = $_W['attachurl'].'headimg_'.$_W['acid'].'.jpg?time='.$_W['timestamp'];
50 $_W['attachurl'] = attachment_set_attach_url();
51
52
53 $engine = new WeEngine();
54 if (!empty($_W['setting']['copyright']['status'])) {
55     $engine->died('抱歉,站点已关闭,关闭原因:' . $_W['setting']['copyright']['reason']);
56 }
57 if (!empty($_W['uniaccount']['endtime']) && TIMESTAMP > $_W['uniaccount']['endtime']) {
58     $engine->died('抱歉,您的公众号已过期,请及时联系管理员');
59 }
60
61 if($_W['isajax'] && $_W['ispost'] && $_GPC['flag'] == 1) {
62     $engine->encrypt();
63 }
64 if($_W['isajax'] && $_W['ispost'] && $_GPC['flag'] == 2) {
65     $engine->decrypt();
66 }
67 load()->func('compat.biz');
68 $_W['isajax'] = false;
69 $engine->start();
70
71
72 class WeEngine {
73     
74     private $account = null;
75     
76     private $modules = array();
77     
78     public $keyword = array();
79     
80     public $message = array();
81
82     
83     public function __construct() {
84         global $_W;
85         $this->account = WeAccount::create($_W['account']);
86         if(strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
87             $_W['modules'] = uni_modules();
88             $this->modules = array_keys($_W['modules']);
89             $this->modules[] = 'cover';
90             $this->modules[] = 'default';
91             $this->modules[] = 'reply';
92             $this->modules = array_unique ($this->modules);
93         }
94     }
95
96     
97     public function encrypt() {
98         global $_W;
99         if(empty($this->account)) {
100             exit('Miss Account.');
101         }
102         $timestamp = TIMESTAMP;
103         $nonce = random(5);
104         $token = $_W['account']['token'];
105         $signkey = array($token, TIMESTAMP, $nonce);
106         sort($signkey, SORT_STRING);
107         $signString = implode($signkey);
108         $signString = sha1($signString);
109
110         $_GET['timestamp'] = $timestamp;
111         $_GET['nonce'] = $nonce;
112         $_GET['signature'] = $signString;
113         $postStr = file_get_contents('php://input');
114         if(!empty($_W['account']['encodingaeskey']) && strlen($_W['account']['encodingaeskey']) == 43 && !empty($_W['account']['key']) && $_W['setting']['development'] != 1) {
115             $data = $this->account->encryptMsg($postStr);
116             $array = array('encrypt_type' => 'aes', 'timestamp' => $timestamp, 'nonce' => $nonce, 'signature' => $signString, 'msg_signature' => $data[0], 'msg' => $data[1]);
117         } else {
118             $data = array('', '');
119             $array = array('encrypt_type' => '', 'timestamp' => $timestamp, 'nonce' => $nonce, 'signature' => $signString, 'msg_signature' => $data[0], 'msg' => $data[1]);
120         }
121         exit(json_encode($array));
122     }
123
124     
125     public function decrypt() {
126         global $_W;
127         if(empty($this->account)) {
128             exit('Miss Account.');
129         }
130         $postStr = file_get_contents('php://input');
131         if(!empty($_W['account']['encodingaeskey']) && strlen($_W['account']['encodingaeskey']) == 43 && !empty($_W['account']['key']) && $_W['setting']['development'] != 1) {
132             $resp = $this->account->local_decryptMsg($postStr);
133         } else {
134             $resp = $postStr;
135         }
136         exit($resp);
137     }
138
139     
140     public function start() {
141         global $_W;
142         if(empty($this->account)) {
143             exit('Miss Account.');
144         }
145         if(!$this->account->checkSign()) {
146             exit('Check Sign Fail.');
147         }
148         if(strtolower($_SERVER['REQUEST_METHOD']) == 'get') {
149             $row = array();
150             $row['isconnect'] = 1;
151             pdo_update('account', $row, array('acid' => $_W['acid']));
152             cache_delete(cache_system_key('uniaccount', array('uniacid' => $_W['uniacid'])));
153             exit(htmlspecialchars($_GET['echostr']));
154         }
155         if(strtolower($_SERVER['REQUEST_METHOD']) == 'post') {
156             $postStr = file_get_contents('php://input');
157                         if(!empty($_GET['encrypt_type']) && $_GET['encrypt_type'] == 'aes') {
158                 $postStr = $this->account->decryptMsg($postStr);
159             }
160             WeUtility::logging('trace', $postStr);
161             $message = $this->account->parse($postStr);
162
163             $this->message = $message;
164             if(empty($message)) {
165                 WeUtility::logging('waring', 'Request Failed');
166                 exit('Request Failed');
167             }
168             $_W['openid'] = $message['from'];
169             $_W['fans'] = array('from_user' => $_W['openid']);
170             $this->booking($message);
171             if($message['event'] == 'unsubscribe') {
172                 $this->receive(array(), array(), array());
173                 exit();
174             }
175             $sessionid = md5($message['from'] . $message['to'] . $_W['uniacid']);
176             session_id($sessionid);
177             WeSession::start($_W['uniacid'], $_W['openid']);
178
179             $_SESSION['openid'] = $_W['openid'];
180             $pars = $this->analyze($message);
181             $pars[] = array(
182                 'message' => $message,
183                 'module' => 'default',
184                 'rule' => '-1',
185             );
186             $hitParam['rule'] = -2;
187             $hitParam['module'] = '';
188             $hitParam['message'] = $message;
189
190             $hitKeyword = array();
191             $response = array();
192             foreach($pars as $par) {
193                 if(empty($par['module'])) {
194                     continue;
195                 }
196                 $par['message'] = $message;
197                 $response = $this->process($par);
198                 if($this->isValidResponse($response)) {
199                     $hitParam = $par;
200                     if(!empty($par['keyword'])) {
201                         $hitKeyword = $par['keyword'];
202                     }
203                     break;
204                 }
205             }
206             $response_debug = $response;
207             $pars_debug = $pars;
208             if($hitParam['module'] == 'default' && is_array($response) && is_array($response['params'])) {
209                 foreach($response['params'] as $par) {
210                     if(empty($par['module'])) {
211                         continue;
212                     }
213                     $response = $this->process($par);
214                     if($this->isValidResponse($response)) {
215                         $hitParam = $par;
216                         if(!empty($par['keyword'])) {
217                             $hitKeyword = $par['keyword'];
218                         }
219                         break;
220                     }
221                 }
222             }
223             WeUtility::logging('params', var_export($hitParam, true));
224             WeUtility::logging('response', $response);
225             $resp = $this->account->response($response);
226                         if(!empty($_GET['encrypt_type']) && $_GET['encrypt_type'] == 'aes') {
227                 $resp = $this->account->encryptMsg($resp);
228                 $resp = $this->account->xmlDetract($resp);
229             }
230             if($_W['debug']) {
231                 $_W['debug_data'] = array(
232                     'resp' => $resp,
233                     'is_default' => 0
234                 );
235                 if(count($pars_debug) == 1) {
236                     $_W['debug_data']['is_default'] = 1;
237                     $_W['debug_data']['params'] = $response_debug['params'];
238                 } else {
239                     array_pop($pars_debug);
240                     $_W['debug_data']['params'] = $pars_debug;
241                 }
242                 $_W['debug_data']['hitparam'] = $hitParam;
243                 $_W['modules']['cover'] = array('title' => '入口封面', 'name' => 'cover');
244
245                 load()->web('template');
246                 $process = template('utility/emulator', TEMPLATE_FETCH);
247                 echo json_encode(array('resp' => $resp, 'process' => $process));
248                 exit();
249             }
250             if ($resp !== 'success') {
251                 $mapping = array(
252                     '[from]' => $this->message['from'],
253                     '[to]' => $this->message['to'],
254                     '[rule]' => $this->params['rule']
255                 );
256                 $resp = str_replace(array_keys($mapping), array_values($mapping), $resp);
257             }
258
259             $reply_times_info = (array)$_SESSION['__reply_times'];
260             if ($reply_times_info['content'] == $message['content']) {
261                 $new_times = intval($reply_times_info['times']) + 1;
262             } else {
263                 $new_times = 1;
264             }
265             $_SESSION['__reply_times'] = array('content' => $message['content'], 'date' => date('Y-m-d'), 'times' => $new_times);
266             ob_start();
267             echo $resp;
268             ob_start();
269             $this->receive($hitParam, $hitKeyword, $response);
270             ob_end_clean();
271             exit();
272         }
273         WeUtility::logging('waring', 'Request Failed');
274         exit('Request Failed');
275     }
276
277     private function isValidResponse($response) {
278         if ($response === 'success') {
279             return true;
280         }
281         if(is_array($response)) {
282             if($response['type'] == 'text' && !empty($response['content'])) {
283                 return true;
284             }
285             if($response['type'] == 'news' && !empty($response['items'])) {
286                 return true;
287             }
288             if(!in_array($response['type'], array('text', 'news', 'image'))) {
289                 return true;
290             }
291         }
292         return false;
293     }
294
295     
296     private function booking($message) {
297         global $_W;
298         if ($message['event'] == 'unsubscribe' || $message['event'] == 'subscribe') {
299             $todaystat = pdo_get('stat_fans', array('date' => date('Ymd'), 'uniacid' => $_W['uniacid']));
300             if ($message['event'] == 'unsubscribe') {
301                 if (empty($todaystat)) {
302                     $updatestat = array(
303                         'new' => 0,
304                         'uniacid' => $_W['uniacid'],
305                         'cancel' => 1,
306                         'cumulate' => 0,
307                         'date' => date('Ymd'),
308                     );
309                     pdo_insert('stat_fans', $updatestat);
310                 } else {
311                     $updatestat = array(
312                         'cancel' => $todaystat['cancel'] + 1,
313                     );
314                     $updatestat['cumulate'] = 0;
315                     pdo_update('stat_fans', $updatestat, array('id' => $todaystat['id']));
316                 }
317             } elseif ($message['event'] == 'subscribe') {
318                 if (empty($todaystat)) {
319                     $updatestat = array(
320                         'new' => 1,
321                         'uniacid' => $_W['uniacid'],
322                         'cancel' => 0,
323                         'cumulate' => 0,
324                         'date' => date('Ymd'),
325                     );
326                     pdo_insert('stat_fans', $updatestat);
327                 } else {
328                     $updatestat = array(
329                         'new' => $todaystat['new'] + 1,
330                         'cumulate' => 0,
331                     );
332                     pdo_update('stat_fans', $updatestat, array('id' => $todaystat['id']));
333                 }
334             }
335         }
336
337         load()->model('mc');
338         $setting = uni_setting($_W['uniacid'], array('passport'));
339         $fans = mc_fansinfo($message['from']);
340         $default_groupid = cache_load(cache_system_key('defaultgroupid', array('uniacid' => $_W['uniacid'])));
341         if (empty($default_groupid)) {
342             $default_groupid = pdo_fetchcolumn('SELECT groupid FROM ' .tablename('mc_groups') . ' WHERE uniacid = :uniacid AND isdefault = 1', array(':uniacid' => $_W['uniacid']));
343             cache_write(cache_system_key('defaultgroupid', array('uniacid' => $_W['uniacid'])), $default_groupid);
344         }
345         if(!empty($fans)) {
346             if ($message['event'] == 'unsubscribe') {
347                 cache_build_memberinfo($fans['uid']);
348                 pdo_update('mc_mapping_fans', array('follow' => 0, 'unfollowtime' => TIMESTAMP), array('fanid' => $fans['fanid']));
349                 pdo_delete('mc_fans_tag_mapping', array('fanid' => $fans['fanid']));
350             } elseif ($message['event'] != 'ShakearoundUserShake' && $message['type'] != 'trace') {
351                 $rec = array();
352                 if (empty($fans['follow'])) {
353                     $rec['follow'] = 1;
354                     $rec['followtime'] = $message['time'];
355                 }
356                 $member = array();
357                 if(!empty($fans['uid'])){
358                     $member = mc_fetch($fans['uid']);
359                 }
360                 if (empty($member)) {
361                     if (!isset($setting['passport']) || empty($setting['passport']['focusreg'])) {
362                         $data = array(
363                             'uniacid' => $_W['uniacid'],
364                             'email' => md5($message['from']).'@we7.cc',
365                             'salt' => random(8),
366                             'groupid' => $default_groupid,
367                             'createtime' => TIMESTAMP,
368                         );
369                         $data['password'] = md5($message['from'] . $data['salt'] . $_W['config']['setting']['authkey']);
370                         pdo_insert('mc_members', $data);
371                         $rec['uid'] = pdo_insertid();
372                     }
373                 }
374                 if(!empty($rec)){
375                     pdo_update('mc_mapping_fans', $rec, array('openid' => $message['from']));
376                 }
377             }
378         } else {
379             if ($message['event'] == 'subscribe' || $message['type'] == 'text' || $message['type'] == 'image') {
380                 load()->model('mc');
381                 $force_init_member = false;
382                 if (!isset($setting['passport']) || empty($setting['passport']['focusreg'])) {
383                     $force_init_member = true;
384                 }
385                 mc_init_fans_info($message['from'], $force_init_member);
386             }
387         }
388     }
389
390     private function receive($par, $keyword, $response) {
391         global $_W;
392         fastcgi_finish_request();
393
394         $subscribe = cache_load(cache_system_key('module_receive_enable'));
395         if (empty($subscribe)) {
396             $subscribe = cache_build_module_subscribe_type();
397         }
398         $modules = uni_modules();
399         $obj = WeUtility::createModuleReceiver('core');
400         $obj->message = $this->message;
401         $obj->params = $par;
402         $obj->response = $response;
403         $obj->keyword = $keyword;
404         $obj->module = 'core';
405         $obj->uniacid = $_W['uniacid'];
406         $obj->acid = $_W['acid'];
407         if(method_exists($obj, 'receive')) {
408             @$obj->receive();
409         }
410         load()->func('communication');
411         if (empty($subscribe[$this->message['type']]) && !empty($this->message['event'])) {
412             $subscribe[$this->message['type']] = $subscribe[strtolower($this->message['event'])];
413         }
414         if (!empty($subscribe[$this->message['type']])) {
415             foreach ($subscribe[$this->message['type']] as $modulename) {
416                                                                 $params = array(
417                     'i' => $GLOBALS['uniacid'],
418                     'modulename' => $modulename,
419                     'request' => json_encode($par),
420                     'response' => json_encode($response),
421                     'message' => json_encode($this->message),
422                 );
423                 $response = ihttp_request(wurl('utility/subscribe/receive'), $params, array(), 10);
424                 if (is_error($response) || $response['code'] != 200) {
425                     $response = ihttp_request($_W['siteroot'] . 'web/' . wurl('utility/subscribe/receive'), $params, array(), 10);
426                 }
427             }
428         }
429     }
430
431     
432     private function analyze(&$message) {
433         global $_W;
434         $params = array();
435         if(in_array($message['type'], array('event', 'qr'))) {
436             $params = call_user_func_array(array($this, 'analyze' . $message['type']), array(&$message));
437             if(!empty($params)) {
438                 return (array)$params;
439             }
440         }
441         if(!empty($_SESSION['__contextmodule']) && in_array($_SESSION['__contextmodule'], $this->modules)) {
442             if($_SESSION['__contextexpire'] > TIMESTAMP) {
443                 $params[] = array(
444                     'message' => $message,
445                     'module' => $_SESSION['__contextmodule'],
446                     'rule' => $_SESSION['__contextrule'],
447                     'priority' => $_SESSION['__contextpriority'],
448                     'context' => true
449                 );
450                 return $params;
451             } else {
452                 unset($_SESSION);
453                 session_destroy();
454             }
455         }
456
457         $reply_times_info = (array)$_SESSION['__reply_times'];
458         if (!empty($_W['account']['setting']) && !empty($reply_times_info) && intval($_W['account']['setting']['reply_setting']) > 0 && strtotime($reply_times_info['date']) >= strtotime(date('Y-m-d')) && $reply_times_info['times'] >= $_W['account']['setting']['reply_setting'] && $reply_times_info['content'] == $message['content']) {
459             exit('success');
460         }
461
462         if(method_exists($this, 'analyze' . $message['type'])) {
463             $temp = call_user_func_array(array($this, 'analyze' . $message['type']), array(&$message));
464             if(!empty($temp) && is_array($temp)){
465                 $params += $temp;
466             }
467         } else {
468             $params += $this->handler($message['type']);
469         }
470         return $params;
471     }
472
473     private function analyzeSubscribe(&$message) {
474         global $_W;
475         $params = array();
476         $message['type'] = 'text';
477         $message['redirection'] = true;
478         if(!empty($message['scene'])) {
479             $message['source'] = 'qr';
480             $sceneid = trim($message['scene']);
481             $scene_condition = '';
482             if (is_numeric($sceneid)) {
483                 $scene_condition = " `qrcid` = '{$sceneid}'";
484             }else{
485                 $scene_condition = " `scene_str` = '{$sceneid}'";
486             }
487             $qr = pdo_fetch("SELECT `id`, `keyword` FROM " . tablename('qrcode') . " WHERE {$scene_condition} AND `uniacid` = '{$_W['uniacid']}'");
488             if(!empty($qr)) {
489                 $message['content'] = $qr['keyword'];
490                 if (!empty($qr['type']) && $qr['type'] == 'scene') {
491                     $message['msgtype'] = 'text';
492                 }
493                 $params += $this->analyzeText($message);
494                 return $params;
495             }
496         }
497         $message['source'] = 'subscribe';
498         $setting = uni_setting($_W['uniacid'], array('welcome'));
499         if(!empty($setting['welcome'])) {
500             $message['content'] = $setting['welcome'];
501             $params += $this->analyzeText($message);
502         }
503
504         return $params;
505     }
506
507     private function analyzeQR(&$message) {
508         global $_W;
509         $params = array();
510         $params = $this->handler($message['type']);
511         if (!empty($params)) {
512             return $params;
513         }
514         $message['type'] = 'text';
515         $message['redirection'] = true;
516         if(!empty($message['scene'])) {
517             $message['source'] = 'qr';
518             $sceneid = trim($message['scene']);
519             $scene_condition = '';
520             if (is_numeric($sceneid)) {
521                 $scene_condition = " `qrcid` = '{$sceneid}'";
522             }else{
523                 $scene_condition = " `scene_str` = '{$sceneid}'";
524             }
525             $qr = pdo_fetch("SELECT `id`, `keyword` FROM " . tablename('qrcode') . " WHERE {$scene_condition} AND `uniacid` = '{$_W['uniacid']}'");
526
527         }
528         if (empty($qr) && !empty($message['ticket'])) {
529             $message['source'] = 'qr';
530             $ticket = trim($message['ticket']);
531             if(!empty($ticket)) {
532                 $qr = pdo_fetchall("SELECT `id`, `keyword` FROM " . tablename('qrcode') . " WHERE `uniacid` = '{$_W['uniacid']}' AND ticket = '{$ticket}'");
533                 if(!empty($qr)) {
534                     if(count($qr) != 1) {
535                         $qr = array();
536                     } else {
537                         $qr = $qr[0];
538                     }
539                 }
540             }
541         }
542         if(!empty($qr)) {
543             $message['content'] = $qr['keyword'];
544             if (!empty($qr['type']) && $qr['type'] == 'scene') {
545                 $message['msgtype'] = 'text';
546             }
547             $params += $this->analyzeText($message);
548         }
549         return $params;
550     }
551
552     public function analyzeText(&$message, $order = 0) {
553         global $_W;
554
555         $pars = array();
556
557         $order = intval($order);
558         if(!isset($message['content'])) {
559             return $pars;
560         }
561                 $condition = <<<EOF
562 `uniacid` IN ( 0, {$_W['uniacid']} )
563 AND
564 (
565     ( `type` = 1 AND `content` = :c1 )
566     or
567     ( `type` = 2 AND instr(:c2, `content`) )
568     or
569     ( `type` = 3 AND :c3 REGEXP `content` )
570     or
571     ( `type` = 4 )
572 )
573 AND `status`=1
574 EOF;
575
576         $params = array();
577         $params[':c1'] = $message['content'];
578         $params[':c2'] = $message['content'];
579         $params[':c3'] = $message['content'];
580
581         if (intval($order) > 0) {
582             $condition .= " AND `displayorder` > :order";
583             $params[':order'] = $order;
584         }
585
586         $keywords = reply_keywords_search($condition, $params);
587         if(empty($keywords)) {
588             return $pars;
589         }
590         foreach($keywords as $keyword) {
591             $params = array(
592                 'message' => $message,
593                 'module' => $keyword['module'],
594                 'rule' => $keyword['rid'],
595                 'priority' => $keyword['displayorder'],
596                 'keyword' => $keyword,
597                 'reply_type' => $keyword['reply_type']
598             );
599             $pars[] = $params;
600         }
601         return $pars;
602     }
603
604     private function analyzeEvent(&$message) {
605         if (strtolower($message['event']) == 'subscribe') {
606             return $this->analyzeSubscribe($message);
607         }
608         if (strtolower($message['event']) == 'click') {
609             $message['content'] = strval($message['eventkey']);
610             return $this->analyzeClick($message);
611         }
612         if (in_array($message['event'], array('pic_photo_or_album', 'pic_weixin', 'pic_sysphoto'))) {
613             pdo_delete('menu_event', array('createtime <' => $GLOBALS['_W']['timestamp'] - 100, 'openid' => $message['from']), 'OR');
614             if (!empty($message['sendpicsinfo']['count'])) {
615                 foreach ($message['sendpicsinfo']['piclist'] as $item) {
616                     pdo_insert('menu_event', array(
617                         'uniacid' => $GLOBALS['_W']['uniacid'],
618                         'keyword' => $message['eventkey'],
619                         'type' => $message['event'],
620                         'picmd5' => $item,
621                         'openid' => $message['from'],
622                         'createtime' => TIMESTAMP,
623                     ));
624                 }
625             } else {
626                 pdo_insert('menu_event', array(
627                     'uniacid' => $GLOBALS['_W']['uniacid'],
628                     'keyword' => $message['eventkey'],
629                     'type' => $message['event'],
630                     'picmd5' => $item,
631                     'openid' => $message['from'],
632                     'createtime' => TIMESTAMP,
633                 ));
634             }
635             $message['content'] = strval($message['eventkey']);
636             $message['source'] = $message['event'];
637             return $this->analyzeText($message);
638         }
639         if (!empty($message['eventkey'])) {
640             $message['content'] = strval($message['eventkey']);
641             $message['type'] = 'text';
642             $message['redirection'] = true;
643             $message['source'] = $message['event'];
644             return $this->analyzeText($message);
645         }
646         return $this->handler($message['event']);
647     }
648
649     private function analyzeClick(&$message) {
650         if(!empty($message['content']) || $message['content'] !== '') {
651             $message['type'] = 'text';
652             $message['redirection'] = true;
653             $message['source'] = 'click';
654             return $this->analyzeText($message);
655         }
656
657         return array();
658     }
659
660     private function analyzeImage(&$message) {
661         load()->func('communication');
662         if (!empty($message['picurl'])) {
663             $response = ihttp_get($message['picurl']);
664             if (!empty($response)) {
665                 $md5 = md5($response['content']);
666                 $event = pdo_get('menu_event', array('picmd5' => $md5), array('keyword', 'type'));
667                 if (!empty($event['keyword'])) {
668                     pdo_delete('menu_event', array('picmd5' => $md5));
669                 } else {
670                     $event = pdo_get('menu_event', array('openid' => $message['from']), array('keyword', 'type'));
671                 }
672                 if (!empty($event)) {
673                     $message['content'] = $event['keyword'];
674                     $message['eventkey'] = $event['keyword'];
675                     $message['type'] = 'text';
676                     $message['event'] = $event['type'];
677                     $message['redirection'] = true;
678                     $message['source'] = $event['type'];
679                     return $this->analyzeText($message);
680                 }
681             }
682             return $this->handler('image');
683         }
684     }
685
686     private function analyzeVoice(&$message) {
687         $params = $this->handler('voice');
688         if (empty($params) && !empty($message['recognition'])) {
689             $message['type'] = 'text';
690             $message['redirection'] = true;
691             $message['source'] = 'voice';
692             $message['content'] = $message['recognition'];
693             return $this->analyzeText($message);
694         } else {
695             return $params;
696         }
697     }
698
699     
700     private function handler($type) {
701         if(empty($type)) {
702             return array();
703         }
704         global $_W;
705         $params = array();
706         $setting = uni_setting($_W['uniacid'], array('default_message'));
707         $default_message = $setting['default_message'];
708         if(is_array($default_message) && !empty($default_message[$type]['type'])) {
709             if ($default_message[$type]['type'] == 'keyword') {
710                 $message = $this->message;
711                 $message['type'] = 'text';
712                 $message['redirection'] = true;
713                 $message['source'] = $type;
714                 $message['content'] = $default_message[$type]['keyword'];
715                 return $this->analyzeText($message);
716             } else {
717                 $params[] = array(
718                     'message' => $this->message,
719                     'module' => is_array($default_message[$type]) ? $default_message[$type]['module'] : $default_message[$type],
720                     'rule' => '-1',
721                 );
722                 return $params;
723             }
724         }
725         return array();
726     }
727
728     
729     private function process($param) {
730         global $_W;
731         if(empty($param['module']) || !in_array($param['module'], $this->modules)) {
732             return false;
733         }
734         if ($param['module'] == 'reply') {
735             $processor = WeUtility::createModuleProcessor('core');
736         } else {
737             $processor = WeUtility::createModuleProcessor($param['module']);
738         }
739         $processor->message = $param['message'];
740         $processor->rule = $param['rule'];
741         $processor->reply_type = $param['reply_type'];
742         $processor->priority = intval($param['priority']);
743         $processor->inContext = $param['context'] === true;
744         $response = $processor->respond();
745         if(empty($response)) {
746             return false;
747         }
748
749         return $response;
750     }
751
752     
753     public function died($content = '') {
754         global $_W, $engine;
755         if (empty($content)) {
756             exit('');
757         }
758         $response['FromUserName'] = $engine->message['to'];
759         $response['ToUserName'] = $engine->message['from'];
760         $response['MsgType'] = 'text';
761         $response['Content'] = htmlspecialchars_decode($content);
762         $response['CreateTime'] = TIMESTAMP;
763         $response['FuncFlag'] = 0;
764         $xml = array2xml($response);
765         if(!empty($_GET['encrypt_type']) && $_GET['encrypt_type'] == 'aes') {
766             $resp = $engine->account->encryptMsg($xml);
767             $resp = $engine->account->xmlDetract($resp);
768         } else {
769             $resp = $xml;
770         }
771         exit($resp);
772     }
773 }
774
775