VbotLib.php 7.1 KB
<?php

namespace addons\vbot\library;

/**
 *
 */
class VbotLib
{
    // 模板数据
    public $template;

    // 要覆盖的模板数据 (参见:\application\admin\controller\dinghorn\Example.php 的 example2 方法)
    public $tpl_data;

    // 模板变量键值对,若模板变量已预先定义,则会自动获取值,无需在此传递
    public $tpl_variable;

    /**
     * 构造方法
     * @param array $template 模板数据
     * @param array $tpl_data 要覆盖的模板数据
     * @param array $tpl_variable 模板变量键值对
     */
    public function __construct($template = array(), $tpl_data = array(), $tpl_variable = array())
    {
        $this->template     = $template;
        $this->tpl_data     = $tpl_data;
        $this->tpl_variable = $tpl_variable;
    }

    /**
     * 发起请求
     *
     * @param string $access_token 机器人的 access_token
     * @param array post_data 请求数据
     * @return array 请求结果
     */
    /**
     * 发起请求
     * @param  string $webhook 机器人的 WebHook地址
     * @param  array $post_data 请求数据
     * @return array             请求结果
     */
    public function msgSend($webhook, $post_data)
    {

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $webhook);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json;charset=utf-8'));
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        $ret = curl_exec($ch);

        if (false == $ret) {
            // curl_exec failed
            $result = ['errcode' => -2, 'errmsg' => curl_error($ch)];
        } else {
            $rsp = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            if (200 != $rsp) {
                $result = ['errcode' => -1, 'errmsg' => $rsp . ' ' . curl_error($ch)];
            } else {
                $result = json_decode($ret, true);
                if (!$result) {
                    $result = ['errcode' => -3, 'errmsg' => '转换请求结果数据失败!'];
                }
            }
        }

        curl_close($ch);
        return $result;
    }

    /**
     * 组装消息数据
     * @return array 组装结果
     */
    public function deal_with_msg()
    {
        $msg_data = array();

        $msgtype = $msg_data['msgtype'] = $this->template['typelist'];

        $content = isset($this->tpl_data['content']) ? $this->analysis_variable($this->tpl_data['content']) : $this->analysis_variable($this->template['content']);

        if ($msgtype == 'text') {

            $msg_data['text'] = [
                'content'               => $content,
                'mentioned_mobile_list' => $this->deal_with_at($this->template)
            ];

        } elseif ($msgtype == 'markdown') {

            $msg_data['markdown'] = [
                'content' => $content
            ];

        } elseif ($msgtype == 'image') {

            $picurl_image = isset($this->tpl_data['picurl_image']) ? $this->tpl_data['picurl_image'] : request()->domain() . $this->template['picurl_image'];

            $base64 = base64_encode(@file_get_contents($picurl_image));

            $msg_data['image'] = [
                'base64' => $base64,
                'md5'    => md5(@file_get_contents($picurl_image))
            ];

        } elseif ($msgtype == 'news') {
            $news = isset($this->tpl_data['news']) ? $this->tpl_data['news'] : json_decode($this->template['news'], true);

            foreach ($news as $key => $value) {
                $news[$key]['title']       = $this->analysis_variable($news[$key]['title']);
                $news[$key]['description'] = '';
            }

            $news[0]['description'] = $content;

            $msg_data['news'] = array(
                'articles' => $news
            );
        }

        return $msg_data;
    }

    /**
     * 分析字符串中的自定义变量
     * @param  string $str 要分析的字符串
     * @return string      解析过变量的字符串
     */
    public function analysis_variable($str)
    {
        if (!$str) {
            return '';
        }

        $variables = array();
        $match     = array();
        preg_match_all('/\${(.*?)}/', $str, $match);// 匹配到所有变量

        // 读取数据库中的模板变量
        $variable_tmp = \think\Db::name('vbot_variable')->where('deletetime', null)->select();
        foreach ($variable_tmp as $key => $value) {
            $value['variable_type']       = 'predefined';// 标记为预定义
            $variable_arr[$value['name']] = $value;
        }
        unset($variable_tmp);

        // 准备传递过来的模板变量
        foreach ($this->tpl_variable as $key => $value) {
            $variable_arr[$key] = [
                'variable_type'  => 'definition_now',// 标记为现在定义
                'variable_value' => $value,
            ];
        }

        foreach ($match[1] as $key => $value) {

            if (array_key_exists($value, $variable_arr)) {

                if ($variable_arr[$value]['variable_type'] == 'definition_now') {

                    $str = str_replace($match[0][$key], $variable_arr[$value]['variable_value'], $str);
                } else if ($variable_arr[$value]['variable_type'] == 'predefined') {

                    $variable_value = $this->get_variable_value($variable_arr[$value]);
                    $str            = str_replace($match[0][$key], $variable_value, $str);
                }
            }
        }

        return $str;
    }

    /**
     * 获取数据库中的模板变量的值
     * @param  string $var 变量数据
     * @return string      变量值
     */
    public function get_variable_value($var)
    {
        if ($var['value_source'] == 0) {
            $var['sql'] = str_replace('__PREFIX__', config('database.prefix'), $var['sql']);
            $res        = \think\Db::query($var['sql']);

            if ($res) {
                if (is_array($res[0])) {
                    foreach ($res[0] as $key => $value) {
                        return $value;
                    }
                } else {
                    return $res[0];
                }
            } else {
                return false;
            }
        } elseif ($var['value_source'] == 1) {
            return \think\Hook::exec($var['namespace'] . '\\' . $var['class'], $var['function'], $var['params']);
        }
    }

    /**
     * 组装at数据
     * @return array 组装结果
     */
    public function deal_with_at()
    {
        if (isset($this->tpl_data['is_atall']) || isset($this->tpl_data['at_mobiles'])) {
            $this->template['is_atall']   = $this->tpl_data['is_atall'];
            $this->template['at_mobiles'] = $this->tpl_data['at_mobiles'];
        }

        if ($this->template['is_atall']) {

            return ['', "@all"];
        } else {
            $at_mobiles = explode(',', rtrim($this->template['at_mobiles'], ','));

            return $at_mobiles;
        }
    }
}