<?php
set_time_limit(0);
/**
 * 搜外网静态文件存储管理
 */
ini_set('display_errors', 1);
error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
if (!class_exists('PDO', false)) {
    res(1003, "空间不支持pdo连接");
}

date_default_timezone_set('PRC');
mb_internal_encoding('utf-8');


$client = new appClient();
$client->run();

class appClient
{
    private $db;
    private $start;
    private $database;

    public function __construct(){
        if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
            exit; // finish preflight CORS requests here
        }

        $this->database = require('config.php');
        $this->start = time();
        $this->db = new pdoMysql($this->database);
    }

    public function run(){
        $funcName = $_GET['a'] . "Action";
        if(!method_exists($this, $funcName))
        {
            die('not allow access!');
        }

        call_user_func([$this, $funcName]);
    }

    public function uploadAction(){
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");

        $file_url = $_POST['file_url'];
        if($file_url){

        }else{
            //只处理第一个文件
            $file = reset($_FILES);
        }
        if ($_REQUEST["name"]) {
            $fileName = $_REQUEST["name"];
        }else if ($_POST["name"]) {
            $fileName = $_POST["name"];
        }else if ($file_url) {
            $fileName = basename($file_url);
        }else{
            $fileName = $file['name'];
        }
        //分离ext
        $ext = '';
        $fileNameArr = explode('.', $fileName);
        if(count($fileNameArr) > 1){
            $ext = array_pop($fileNameArr);
            $fileName = implode('', $fileNameArr);
        }

        $is_image = false;
        //支持的格式
        if(!in_array($ext, ['text','xmind','xlsx','xls','zip','doc','docx','rar','ppt','pptx','pdf', 'jpg', 'png', 'gif', 'jpeg', 'bmp'])){
            res(-1, '格式不正确');
        }

        if(in_array($ext, ['jpg', 'png', 'gif', 'jpeg', 'bmp'])){
            $is_image = true;
        }
        //todo 暂不支持分片上传
        //获取filepath，如果指定了filpath，则按filepath来存放
        $dirname = $_POST['dirname'];
        if(!in_array($dirname, [
            'weixin_qr_code',
            'attach',
            'images',
            'avatar',
            'course',
            'article',
            'questions',
            'voice',
            'verify',
            'user',
            'topic',
            'site',
            'medal',
            'feature',
            'card',
            'experience',
            'category',
            'answer',
            'event',
			'lesson'])){
            $dirname = 'images';
        }
        $filepath = ltrim($_POST['filepath'], '/');
        $savePath = __DIR__;
        $newPath  = '/';
        if(!$filepath){
            if($dirname){
                $newPath  .= $dirname . '/';
            }
            $newPath .= date("ym") . "/" . date("d") . "/";
            $newFileName = uniqid() . '.' . $ext;
        }else{
            $newPath .= dirname($filepath) . "/";
            $newFileName = basename($filepath);
        }
        if(!file_exists($savePath . $newPath)){
            mkdir($savePath . $newPath, 0755, true);
        }
        if(!$filepath){

        }else{
            $newFileName = basename($filepath);
        }
        $savePath .= $newPath . $newFileName;

        //判断是否已经上传过了
        if($file) {
            $fileMd5 = md5_file($file['tmp_name']);
            $exists = $this->db->getOne("*", "attachment", "md5 = '$fileMd5'");
            if ($exists && $dirname != 'avatar') {
                //文件已经存在，则，直接返回，不重新写入
                res(0, '文件已存在', [
                    'file_location' => $exists['file_location'],
                    'thumb' => $exists['thumb'],
                    'is_image' => $exists['type'] == 0 ? 1 : 0,
                    'mid'      => str_replace('min_' , 'mid_', $exists['thumb']),
                ]);
            }
        }

        //开始上传文件操作
        if($file_url){
            if (!$file_stream = $this->curlGetContent($file_url)) {
                res(-1, "上传文件失败");
            }
            $fileMd5 = md5($file_stream);
            if (!@file_put_contents($savePath, $file_stream)) {
                res(-1, "上传文件失败");
            }
            $fileSize = strlen($file_stream);
        }else {
            if (!move_uploaded_file($file['tmp_name'], $savePath)) {
                res(-1, "上传文件失败");
            }
            $fileSize = $file['size'];
        }
        @chmod($savePath, 0644);
        //上传完成。
        //开始生成缩略图
        if($is_image) {
            $image = new image();
            $thumbnailUrl = $image->open($savePath)->maxZoom()->quickThumb($dirname);
            $thumbnailUrl = str_replace(__DIR__, '', $thumbnailUrl);
            $midUrl = str_replace('min_', 'mid_', $thumbnailUrl);
        }

        $this->db->insert([
            "md5"           => $fileMd5,
            'file_location' => $newPath . $newFileName,
            'thumb'         => $thumbnailUrl,
            'file_size'     => $fileSize,
            'type'          => $is_image ? 0 : 1,//图片
            'add_time'      => time(),
            'file_name'     => $fileName,
            'ext'           => $ext,
        ], "attachment");

        res(0, '上传成功', [
            'file_location' => $newPath . $newFileName,
            'thumb'         => $thumbnailUrl,
            'is_image'      => $is_image,
            'mid'           => $midUrl,
        ]);
    }

    public function downloadAction(){
        $filepath = @base64_decode(str_replace(' ', '+', $_GET['path']));
        $filename = trim(@base64_decode(str_replace(' ', '+', $_GET['name'])));

        if(!$filepath){
            die('文件不存在');
        }
        //查询
        $filepath = __DIR__ . str_replace('https://static.seowhy.com', '', $filepath);
        if(!file_exists($filepath)){
            die('文件不存在');
        }

        if(!$filename) $filename = basename($filepath);

        if($this->is_ie()) $filename = rawurlencode($filename);
        $filetype = $this->fileext($filename);
        $filesize = sprintf("%u", filesize($filepath));
        if(ob_get_length() !== false) @ob_end_clean();
        //var_dump($filesize, $filetype);die;
        header('Pragma: public');
        header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: no-store, no-cache, must-revalidate');
        header('Cache-Control: pre-check=0, post-check=0, max-age=0');
        header('Content-Transfer-Encoding: binary');
        header('Content-Encoding: none');
        header('Content-type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.$filename.'"');
        header('Content-length: '.$filesize);
        readfile($filepath);
    }

    public function curlGetContent($url, $timeout = 2){
        $opts = array(
            'http'=>array(
                'method'=>"GET",
                'timeout'=>$timeout,
            )
        );
        $context = stream_context_create($opts);
        return file_get_contents($url, false, $context);
    }

    function is_ie()
    {
        $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
        if((strpos($useragent, 'opera') !== false) || (strpos($useragent, 'konqueror') !== false)) return false;
        if(strpos($useragent, 'msie ') !== false) return true;
        return false;
    }

    function fileext($filename)
    {
        return addslashes(strtolower(substr(strrchr($filename, '.'), 1, 10)));
    }
}

/**
 * 数据库操作类
 */
class pdoMysql
{
    private $config = null;
    /** @var PDO */
    public $link = null;
    /** @var PDOStatement|int */
    public $lastqueryid = null;
    public $querycount = 0;

    public function __construct($config)
    {
        if (!$config['port']) {
            $config['port'] = 3306;//默认端口
        }
        if (!$config['charset']) {
            $config['charset'] = 'utf8';
        }
        $this->config = $config;
        $this->config['dsn'] = 'mysql:host=' . $config['host'] . ';port=' . $config['port'] . ';dbname=' . $config['database'];
        $this->connect();
    }

    public function connect()
    {
        try {
            $this->link = new PDO($this->config['dsn'], $this->config['user'], $this->config['password'], array(
                PDO::ATTR_PERSISTENT         => true,
                PDO::ATTR_EMULATE_PREPARES   => false,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES {$this->config['charset']}"
            ));
        } catch (Exception $e) {
            res(-1, $e->getMessage());
        }
        //重置sql_mode,防止datetime,group by 出错
        $this->link->query("set sql_mode=''");

        return $this->link;
    }

    private function execute($sql)
    {
        if (!is_object($this->link)) {
            $this->connect();
        }
        $this->lastqueryid = $this->link->exec($sql);
        $this->querycount++;

        return $this->lastqueryid;
    }

    public function query($sql = null)
    {
        if (!is_object($this->link)) {
            $this->connect();
        }
        $this->lastqueryid = $this->link->query($sql) or $this->halt("", $sql);
        $this->querycount++;

        return $this->lastqueryid;
    }

    public function select($data, $table, $where = '', $limit = '', $order = '', $group = '', $key = '')
    {
        $where = $where == '' ? '' : ' WHERE ' . $where;
        $order = $order == '' ? '' : ' ORDER BY ' . $order;
        $group = $group == '' ? '' : ' GROUP BY ' . $group;
        $limit = $limit == '' ? '' : ' LIMIT ' . $limit;
        $field = explode(',', $data);
        array_walk($field, array($this, 'addSpecialChar'));
        $data = implode(',', $field);
        $result = array();
        $sql = 'SELECT ' . $data . ' FROM `' . $this->config['database'] . '`.`' . $this->getTable($table) . '`' . $where . $group . $order . $limit;

        $this->query($sql);
        if (!is_object($this->lastqueryid)) {
            return $this->lastqueryid;
        }
        $datalist = $this->lastqueryid->fetchAll();
        if ($key) {
            $datalist_new = array();
            foreach ($datalist as $i => $item) {
                $datalist_new[$item[$key]] = $item;
            }
            $datalist = $datalist_new;
            unset($datalist_new);
        }
        $this->freeResult();

        return $datalist;
    }

    public function getOne($data, $table, $where = '', $order = '', $group = '')
    {
        $where = $where == '' ? '' : ' WHERE ' . $where;
        $order = $order == '' ? '' : ' ORDER BY ' . $order;
        $group = $group == '' ? '' : ' GROUP BY ' . $group;
        $limit = ' LIMIT 1';
        $field = explode(',', $data);
        array_walk($field, array($this, 'addSpecialChar'));
        $data = implode(',', $field);
        $sql = 'SELECT ' . $data . ' FROM `' . $this->config['database'] . '`.`' . $this->getTable($table) . '`' . $where . $group . $order . $limit;
        $this->query($sql);
        $res = $this->lastqueryid->fetch();
        $this->freeResult();

        return $res;
    }

    public function getOneCol($data, $table, $where = '', $order = '', $group = '')
    {
        $where = $where == '' ? '' : ' WHERE ' . $where;
        $order = $order == '' ? '' : ' ORDER BY ' . $order;
        $group = $group == '' ? '' : ' GROUP BY ' . $group;
        $limit = ' LIMIT 1';
        $field = explode(',', $data);
        array_walk($field, array($this, 'addSpecialChar'));
        $data = implode(',', $field);
        $fieldname = str_replace('`', '', $data);
        $sql = 'SELECT ' . $data . ' FROM `' . $this->config['database'] . '`.`' . $this->getTable($table) . '`' . $where . $group . $order . $limit;
        $this->query($sql);
        $res = $this->lastqueryid->fetch();
        $this->freeResult();

        return isset($res[$fieldname]) ? $res[$fieldname] : false;
    }

    public function insert($data, $table, $return_insertId = false, $replace = false)
    {
        if (!is_array($data) || $table == '' || count($data) == 0) {
            return false;
        }
        $fielddata = array_keys($data);
        $valuedata = array_values($data);
        array_walk($fielddata, array($this, 'addSpecialChar'));
        array_walk($valuedata, array($this, 'escapeString'));
        $field = implode(',', $fielddata);
        $value = implode(',', $valuedata);
        $cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';
        $sql = $cmd . ' `' . $this->config['database'] . '`.`' . $this->getTable($table) . '`(' . $field . ') VALUES (' . $value . ')';
        $return = $this->execute($sql);

        return $return_insertId ? $this->insertId() : $return;
    }

    /**
     * update 不支持order by
     * @param        $data
     * @param        $table
     * @param string $where
     * @param string $order
     * @param string $limit
     * @return bool|int|PDOStatement
     */
    public function update($data, $table, $where = '', $order = "", $limit = "")
    {
        if ($table == '' or $where == '') {
            return false;
        }
        $where = ' WHERE ' . $where;
        if (is_string($data) && $data != '') {
            $field = $data;
        } elseif (is_array($data) && count($data) > 0) {
            $fields = array();
            foreach ($data as $k => $v) {
                switch (substr($v, 0, 2)) {
                    case '+=':
                        $v = substr($v, 2);
                        if (is_numeric($v)) {
                            $fields[] = $this->addSpecialChar($k) . '=' . $this->addSpecialChar($k) . '+' . $this->escapeString($v, '', false);
                        }
                        break;
                    case '-=':
                        $v = substr($v, 2);
                        if (is_numeric($v)) {
                            $fields[] = $this->addSpecialChar($k) . '=' . $this->addSpecialChar($k) . '-' . $this->escapeString($v, '', false);
                        }
                        break;
                    default:
                        //对自增自减字段的特殊处理
                        if (preg_match('/^`[a-z_0-9]+`\s*[\+\-]\s*[0-9]+$/', $v)) {
                            $fields[] = $this->addSpecialChar($k) . '=' . $v;
                        } else {
                            $fields[] = $this->addSpecialChar($k) . '=' . $this->escapeString($v);
                        }
                }
            }
            $field = implode(',', $fields);
        } else {
            return false;
        }
        $order = !empty($order) ? " ORDER BY " . $order : "";
        $limit = !empty($limit) ? " LIMIT " . $limit : "";
        $sql = 'UPDATE `' . $this->config['database'] . '`.`' . $this->getTable($table) . '` SET ' . $field . $where . $order . $limit;

        return $this->execute($sql);
    }

    public function delete($table, $where)
    {
        if ($table == '' || $where == '') {
            return false;
        }
        $where = ' WHERE ' . $where;
        $sql = 'DELETE FROM `' . $this->config['database'] . '`.`' . $this->getTable($table) . '`' . $where;

        return $this->execute($sql);
    }

    public function count($where = '', $table, $group = '')
    {
        $r = $this->getOne("COUNT(*) AS num", $table, $where, '', $group);

        return $r['num'];
    }

    public function fetchAll($res = null)
    {
        $type = PDO::FETCH_ASSOC;
        if ($res) {
            $res_query = $res;
        } else {
            $res_query = $this->lastqueryid;
        }

        return $res_query->fetchAll($type);
    }

    public function affectedRows()
    {
        return is_numeric($this->lastqueryid) ? $this->lastqueryid : 0;
    }

    public function getPrimary($table)
    {
        $this->query("SHOW COLUMNS FROM " . $this->getTable($table));
        while ($r = $this->lastqueryid->fetch()) {
            if ($r['Key'] == 'PRI') break;
        }

        return $r['Field'];
    }

    public function getFields($table)
    {
        $fields = array();
        $this->query("SHOW COLUMNS FROM " . $this->getTable($table));
        while ($r = $this->lastqueryid->fetch()) {
            $fields[$r['Field']] = $r['Type'];
        }

        return $fields;
    }

    public function checkFields($table, $array)
    {
        $fields = $this->getFields($table);
        $nofields = array();
        foreach ($array as $v) {
            if (!array_key_exists($v, $fields)) {
                $nofields[] = $v;
            }
        }

        return $nofields;
    }

    public function tableExists($table)
    {
        $tables = $this->listTables();

        return in_array($table, $tables) ? 1 : 0;
    }

    public function listTables()
    {
        $tables = array();
        $this->query("SHOW TABLES");
        while ($r = $this->lastqueryid->fetch()) {
            $tables[] = $r['Tables_in_' . $this->config['database']];
        }

        return $tables;
    }

    public function fieldExists($table, $field)
    {
        $fields = $this->getFields($table);

        return array_key_exists($field, $fields);
    }

    public function getTable($table)
    {
        if (!$this->config['prefix']) {
            return $table;
        }
        if (strpos($table, $this->config['prefix']) === false) {
            return $this->config['prefix'] . $table;
        }

        return $table;
    }

    public function numRows($sql)
    {
        $this->query($sql);

        return $this->lastqueryid->rowCount();
    }

    public function num_fields($sql)
    {
        $this->query($sql);

        return $this->lastqueryid->columnCount();
    }

    public function result($sql, $row)
    {
        $this->query($sql);

        return $this->lastqueryid->fetchColumn($row);
    }

    public function error()
    {
        return $this->link->errorInfo();
    }

    public function errno()
    {
        return intval($this->link->errorCode());
    }

    public function insertId()
    {
        return $this->link->lastInsertId();
    }

    public function freeResult()
    {
        if (is_object($this->lastqueryid)) {
            $this->lastqueryid = null;
        }
    }

    public function close()
    {
        if (is_object($this->link)) {
            unset($this->link);
        }
    }

    /**
     * 对字段两边加反引号，以保证数据库安全
     * @param $value 数组值
     * @return mixed|string|数组值
     */
    public function addSpecialChar(&$value)
    {
        if ('*' == $value || false !== strpos($value, '(') || false !== strpos($value, '.') || false !== strpos($value, '`') || false !== strpos(strtolower($value), 'as')) {
            //不处理包含* 或者 使用了sql方法, 使用了别名。
        } else {
            $value = '`' . trim($value) . '`';
        }
        if (preg_match("/\b(select|insert|update|delete)\b/i", $value)) {
            $value = preg_replace("/\b(select|insert|update|delete)\b/i", '', $value);
        }

        return $value;
    }

    /**
     * 对字段值两边加引号，以保证数据库安全
     * @param              $value 数组值
     * @param string|数组key $key 数组key
     * @param int          $quotation
     * @return string|数组值
     */
    public function escapeString(&$value, $key = '', $quotation = 1)
    {
        if ($quotation) {
            $q = '\'';
        } else {
            $q = '';
        }
        $value = $q . $value . $q;

        return $value;
    }

    public function halt($message = '', $sql = '')
    {
        res(-1, 'Errno :' . implode(' ', $this->link->errorInfo()));
    }
}

class image
{
    public $source_image;
    public $output_source;
    public $defaultMaxWidth = 800;
    /** @var Imagick $im */
    public $im;

    /**
     * @param $source_image
     * @param bool $source
     * @return image
     */
    public function open($source_image, $source = false){
        $this->source_image = $source_image;

        try {
            $this->im = new Imagick();
            if($source){
                $this->im->readImageBlob($source_image);
            }else{
                $this->im->readImage($this->source_image);
            }
        }catch (ImagickException $e){
            unset($this->im);
        }

        return $this;
    }

    public function maxZoom(){
        if(!$this->im){
            return false;
        }

        $maxWidth = $this->defaultMaxWidth;

        $imageType = $this->im->getImageFormat();
        if($imageType == 'GIF') {
            //gif不做处理
            return false;
        }

        $this->resize($maxWidth, null, 2)->output(2);

        return $this;
    }

    public function quickThumb($type = null, $source_url = null){
        if(!$this->im){
            return false;
        }
        $thumbnail = [
            'course' => [
                'max' => [
                    'w' => 450,
                    'h' => 380
                ],
                'mid' => [
                    'w' => 225,
                    'h' => 140
                ],
                'min' => [
                    'w' => 147,
                    'h' => 109
                ],
            ],
            'avatar' => [
                'max' => [
                    'w' => 100,
                    'h' => 100
                ],
                'mid' => [
                    'w' => 50,
                    'h' => 50
                ],
                'min' => [
                    'w' => 32,
                    'h' => 32
                ],
            ],
            'attachment' => [
                'mid' => [
                    'w' => 640,
                    'h' => 360
                ],
                'min' => [
                    'w' => 160,
                    'h' => 160
                ],
            ],
            'site' => [
                'thumb' => [
                    'w' => 240,
                    'h' => 135
                ],
                'min' => [
                    'w' => 160,
                    'h' => 160
                ],
            ]
        ];

        if(!$source_url){
            $source_url = $this->source_image;
        }

        $thumbnailUrl = '';
        foreach ($thumbnail['attachment'] as $key => $value){
            $baseName = basename($source_url);
            $newUrl = dirname($source_url) . '/' . $key . '_' . $baseName;
            if($key == 'min'){
                $thumbnailUrl = $newUrl;
            }
            $this->resize($value['w'], $value['h'], 1)->output(2, $newUrl);
        }
        if(in_array($type, ['category', 'avatar', 'course', 'topic'])) {
            foreach ($thumbnail[$type] as $key => $value) {
                $baseName = basename($source_url);
                if ($type == 'avatar' || $type == 'category') {
                    //采用另一种方式
                    $newUrl = str_replace('real', $key, $source_url);
                } elseif ($type == 'course') {
                    $newUrl = dirname($source_url) . '/' . $value['w'] . '_' . $value['h'] . '_' . $baseName;
                } elseif ($type == 'topic') {
                    $sourceArr = explode('.', $source_url);
                    $sourceArr[0] .= "_" . $value['w'] . '_' . $value['h'];
                    $newUrl = implode('.', $sourceArr);
                }

                if ($key == 'min') {
                    $thumbnailUrl = $newUrl;
                }

                $this->resize($value['w'], $value['h'], 1)->output(2, $newUrl);
            }
        }

        return $thumbnailUrl;
    }

    /**
     * @param null $width
     * @param null $height
     * @param int $crop 缩放类型,0 补白,1 居中裁剪, 2 等比缩放
     * @return $this
     */
    public function resize($width = null, $height = null, $crop = 0)
    {
        if(!$this->im){
            return false;
        }

        $imageType = $this->im->getImageFormat();
        if($imageType == 'GIF') {
            //gif不做处理
            return $this;
        }
        if ($crop == 2) {
            if(!$width AND !$width){
                return $this;
            }
            //只有大于缩放尺寸才缩放
            if($this->im->getImageWidth() <= $width){
                return $this;
            }
            if(!$height){
                $height = $width/$this->im->getImageWidth() * $this->im->getImageHeight();
            }
            if(!$width){
                $width = $height/$this->im->getImageHeight() * $this->im->getImageWidth();
            }

            $this->im->resizeImage($width, $height, Imagick::FILTER_CATROM, 1, true);
        }elseif ($crop == 1) {
            $this->im->cropThumbnailImage($width, $height);
        } else {
            if($imageType == "PNG") {
                $this->im->resizeImage($width, $height, Imagick::FILTER_CATROM, 1, true);
                $sourceX = 0;
                $sourceY = 0;
                if ($this->im->getImageWidth() < $width) {
                    $sourceX = ($width - $this->im->getImageWidth()) / 2;
                } elseif ($this->im->getImageHeight() < $height) {
                    $sourceY = ($height - $this->im->getImageHeight()) / 2;
                }
                $canvas = new Imagick;
                $canvas->newImage($width, $height, 'transparent');
                $canvas->compositeImage($this->im, Imagick::COMPOSITE_OVER, $sourceX, $sourceY);
                $canvas->setImageFormat($imageType);
                $this->im = $canvas;
            }else{
                $this->im->thumbnailImage($width, $height, true, true);
            }
        }

        if($imageType == 'JPEG'){
            //$a = $this->im->getImageCompressionQuality() * 0.75;
            $a = $this->im->getImageCompressionQuality();

            if ($a > 85) {
                $this->im->setImageCompressionQuality(85);
            }
            if($a < 75){
                $this->im->setImageCompressionQuality(75);
            }
        }

        $this->im->stripImage();

        return $this;
    }

    public function insertImage($insert_image, $gravity = Imagick::GRAVITY_SOUTHEAST){
        if(!$this->im){
            return false;
        }

        $watermark = new Imagick();
        $watermark->readImage($insert_image);
        $waterInfo = $watermark->getImageGeometry();
        $imInfo    = $this->im->getImageGeometry();

        //占了大于1/4的水印不加
        if($imInfo['width'] < $waterInfo['width'] OR ($waterInfo['width'] > ($imInfo['width']/2) AND $waterInfo['height'] > ($imInfo['height']/2))){
            return $this;
        }

        $dw = new ImagickDraw();
        $dw->setGravity($gravity);
        $dw->composite($watermark->getImageCompose(), 10, 10, 0, 0, $watermark);
        $this->im->drawImage($dw);

        $watermark->destroy();
        $dw->destroy();

        return $this;
    }

    public function insertText($text, $gravity = Imagick::GRAVITY_SOUTHEAST, $size = 32){
        if(!$this->im){
            return false;
        }

        //原图宽度小于100px的不加水印
        if($this->im->getImageWidth() < 100){
            return $this;
        }
        $dw = new ImagickDraw();
        //思源黑体,中等
        //$dw->setFont(V5_LIB_ROOT . 'source/font/SourceHanSans-Medium.otf');
        $dw->setFontSize($size);
        $dw2 = clone $dw;

        $dw->setFillColor(new ImagickPixel("#333333"));
        $dw->setGravity($gravity);
        $dw->annotation(9, 9, $text);

        $dw2->setFillColor(new ImagickPixel("#ccc"));
        $dw2->setGravity($gravity);
        $dw2->annotation(10, 10, $text);

        $this->im->drawImage($dw);
        $this->im->drawImage($dw2);
        $dw->destroy();
        $dw2->destroy();

        return $this;
    }

    /**
     * @param int  $output 0 返回字符串,1 直接输出,2 保存文件
     * @param null $new_path
     * @return string
     */
    public function output($output = 0, $new_path = null){
        if(!$this->im){
            return false;
        }

        $this->output_source = $this->im->getimageblob();
        $outputtype = $this->im->getImageFormat();
        if($output == 1){
            //$this->im->destroy();
            header("Content-type: $outputtype");
            echo $this->output_source;
            die();
        }elseif($output == 2){
            if(!$new_path){
                $new_path = $this->source_image;
            }
            $this->im->writeImage($new_path);
            //$this->im->destroy();
            return true;
        }else {
            //$this->im->destroy();
            return $this->output_source;
        }
    }

    public function getImageWidth(){
        if($this->im){
            return $this->im->getImageWidth();
        }
        return false;
    }

    public function getImageHeight(){
        if($this->im) {
            return $this->im->getImageHeight();
        }
        return false;
    }

    public function destroy(){
        if($this->im) {
            $this->im->destroy();
        }
        return false;
    }
}

/**
 * json输出
 * @param      $code
 * @param null $msg
 * @param null $data
 * @param null $extra
 */
function res($code, $msg = null, $data = null, $extra = null)
{
    @header('Content-Type:application/json;charset=UTF-8');
    $output = array(
        'code' => $code,
        'msg'  => $msg,
        'data' => $data
    );
    if (is_array($extra)) {
        foreach ($extra as $key => $val) {
            $output[$key] = $val;
        }
    }
    echo json_encode($output, JSON_UNESCAPED_UNICODE);
    die;
}
