<?php
/**
 * JYmusic音乐管理系统
 * @version    2.0
 * @author     战神~~巴蒂 <jyuucn@163.com>
 * @license    http://jyuu.cn/license
 * @copyright  2014 - 2017 JYmusic
 */
namespace addons\Upload\controller;

use FtpClient\FtpClient;
use app\services\Uploader;

/**
 * 上传插件FTP驱动
 */
class FtpController extends BaseController
{
    /**
     * @var
     */
    protected $ftp;
    /**
     * @var
     */
    protected $server;
    /**
     * @var
     */
    protected $uploadConf;

    public function _initialize()
    {
        $this->uploadConf = get_addon_config('Upload');
        $this->ftp        = new FtpClient();
    }

    //用户上传需要验证token
    public function index()
    {
        $fileType   = text_filter($this->request->param('file_type', ''));
        $uploadType = text_filter($this->request->param('upload_type', ''));
    
        if ($this->initFtp()) {
            $validation = $this->getValid($fileType);
            if (false === $validation) {
                $this->response['code'] = 40029;
                $this->response['error'] = lang(40029);
            } else {
                $this->validation = $validation;
                $this->$fileType($uploadType);
            }
        }
        
        return json($this->response, 200);
    }

    /**
     * 监听音频上传文件
     * @param string $type
     */
    public function audio($type)
    {
        $maxSize = $this->uploadConf['local_audio_max_size'];
        $maxSize = $maxSize ? $maxSize  : 10; //单位M
        
        if ('down' == $type) {
            $savePath = $this->uploadConf['ftp_audio_down_path'];
        } else {
            $savePath = $this->uploadConf['ftp_audio_listen_path'];
        }
        $this->single($maxSize, $savePath);
    }
    
    /**
     * 监听图片上传文件
     * @param string $type
     */
    public function image($type)
    {
        $maxSize = $this->uploadConf['ftp_image_max_size'];
        $maxSize = $maxSize ? $maxSize  : 10; //单位M
        
        $savePath = $this->uploadConf['ftp_image_path'];
    
        $this->single($maxSize, $savePath);
    
        //图片需要单独设置返回全路径
        if ($this->response['files'][0] === 0) {
            $this->response['files'][0]['filepath'] = rtrim($this->server['image_url'], '/') . $this->response['files'][0]['filepath'];
        }
        
        if ($type == 'wangEdit2') {
            return $this->retWangEdit2();
        } elseif ($type == 'wangEdit3') {
            return $this->retWangEdit2();
        }
    }
    
    /**
     * 上传文件
     * @param  int $maxSize
     * @param  string $savePath 文件保存的路径
     * @param  string $saveName 文件保存的名称
     * @return boolean
     */
    private function single($maxSize, $savePath, $saveName = null)
    {
        $options = [
            'maxSize' =>  $maxSize * 1024 * 1024,
            'extensions' => $this->validation['extensions'],
            'mimeTypes' => $this->validation['mimeTypes'],
        ];
    
        $uploader = new Uploader('files', $options);
        $result = $uploader->getResult();
        $fileInfo = $result['files'][0];
        
        if (false === $uploader->factory()) {
            $this->response['code'] = $fileInfo['errorCode'];
            $this->response['error'] = $fileInfo['error'];
            return false;
        }
        
        //检测目录
        $rootPath = str_replace(['\\', './'], '/', $savePath);
        $rootPath = 0 !== strpos($rootPath, '/') ? '/' . $rootPath : $rootPath;
        $savePath = rtrim($rootPath, '/') . '/' . date('Y-m-d');

        //创建目录
        if (!$this->ftp->isDir($savePath) && !$this->ftp->mkdir($savePath)) {
            $this->response['error'] = 'FTP下' .$rootPath. '目录没有可写权限';
            return false;
        }
        
        $saveFile = $savePath . '/' . $fileInfo['name'];
        
        try {
            $this->ftp->putFromString($saveFile, file_get_contents($fileInfo['tmp_name']));
            $this->response['files'][] = [
                'filepath' => $saveFile,
                'name'     => $fileInfo['name'],
                'size'     => $fileInfo['size'],
                'format_size'     => $fileInfo['format_size'],
                'mime'     => $fileInfo['mime_type'],
                'md5'      => $fileInfo['md5'],
                'sha1'     => $fileInfo['sha1'],
                'location' => $this->server['id'],
                'code' => 0
            ];
            $this->response['code'] = 0;
            return true;
        } catch (\Exception $e) {
            $this->response['code'] = 40500;
            $this->response['error'] = $e->getMessage();
        }
        //上传失败获取错误信息
        return false;
    }

    /**
     * 检测配置参数是否正确
     * @return boolean
     */
    private function initFtp()
    {
        $this->response['code'] = 40030;
        $serverId = $this->uploadConf['ftp_bind_server'];
        $servers  = get_server();

        if (!intval($serverId) || !isset($servers[$serverId])) {
            $this->response['error'] = 'FTP配置错误，没有绑定服务器';
            return false;
        }
        
        $this->server = $servers[$serverId];
        $isSsl = false; //FTP长连接

        try {
            $this->ftp->connect(
                $this->uploadConf['ftp_host'],
                $isSsl, $this->uploadConf['ftp_port'],
                $this->uploadConf['ftp_timeout']
            );
        } catch (\Exception $e) {
            $this->response['error'] = 'FTP服务器链接失败';
            return false;
        }

        try {
            $this->ftp->login($this->uploadConf['ftp_user'], $this->uploadConf['ftp_pwd']);
        } catch (\Exception $e) {
            $this->response['error'] = 'FTP服务器登录失败，请检查用户名或密码是否正确';
            return false;
        }
        $this->response['code'] = 0;
        return true;
    }
}
