<?php namespace Phpcmf\Home;

/**
  * http://www.diyuncms.com
 * 本文件是框架系统文件，二次开发时不可以修改本文件，可以通过继承类方法来重写此文件
 **/

// 用于前端模块评论显示
class Mform extends \Phpcmf\Common
{
    protected $cid;
    protected $index;
    protected $cname; // 评论别名
    public $module; // 模块信息
    public $fid; // 表单
    public $form; // 表单
    public $comment_model; // 评论模型

    // 上级公共类
    public function __construct(...$params) {
        parent::__construct(...$params);
        $this->_Extend_Init();
    }

    // 继承类初始化
    protected function _Extend_Init() {
        // 初始化模块

        $this->_module_init(APP_DIR);
        $fid = str_replace(['_comment_verify', '_comment'], '', \Phpcmf\Service::L('Router')->class);
        if (!$this->module['form'][$fid]) {
            $this->_admin_msg(0, dr_lang('模块【%s】表单【%s】不存在', APP_DIR, $fid));
        }
        $cache = \Phpcmf\Service::L('cache')->get('app-comment-'.SITE_ID, 'mform', APP_DIR.'-'.$fid);
        $this->fid = $fid;
        $this->form = $this->module['form'][$fid];
        $this->cname = dr_comment_cname($cache['cname']);
        $this->module['comment'] = $cache;
        if (!$cache) {
            $this->_admin_msg(0, dr_lang('模块【%s】表单【%s】没有安装%s', APP_DIR, $fid, $this->cname));
        } elseif (!$cache['use']) {
            $this->_admin_msg(0, dr_lang('模块【%s】表单【%s】没有启用%s', APP_DIR, $fid, $this->cname));
        }
        $this->comment_model = \Phpcmf\Service::M('mform', 'comment')->_init($this->module, $fid, SITE_ID, $cache);

        // 关联内容数据
        $this->cid = intval(\Phpcmf\Service::L('input')->get('id'));
        $this->index = $this->comment_model->get_row($this->cid);
        if (!$this->index) {
            $this->_msg(0, dr_lang('模块【%s】表单【%s】内容【id#%s】不存在', APP_DIR, $fid, $this->cid));
        }
        // 格式化输出自定义字段
        $fields = $this->form['field'];
        $fields['inputtime'] = ['fieldtype' => 'Date'];
        $fields['updatetime'] = ['fieldtype' => 'Date'];
        $this->index = \Phpcmf\Service::L('Field')->app($this->module['dirname'])->format_value($fields, $this->index);
        \Phpcmf\Service::V()->module(MOD_DIR);
    }

    // 评论列表
    protected function _Index() {

        // 排序模式
        $type = (int)str_replace('#', '', \Phpcmf\Service::L('input')->get('type'));
        $order = 'inputtime desc';
        switch ($type) {
            case 1:
                $order = 'inputtime asc';
                break;
            case 2:
                $order = 'support asc';
                break;
            case 3:
                $order = 'avgsort desc';
                break;
            case 4:
                $order = 'image desc';
                break;
            default:
                $_GET['order'] && $order = strtolower(dr_get_order_string($_GET['order'], $order));
                break;
        }

        // 判断排序字段是否可用

        if (!dr_in_array(trim(str_replace([' asc', ' desc'], '', $order)), \Phpcmf\Service::L('cache')->get('table-'.SITE_ID, \Phpcmf\Service::M()->dbprefix($this->content_model->mytable.'_comment')))) {
            if (isset($this->module['comment']['order']) && $this->module['comment']['order']) {
                $order = $this->module['comment']['order'];
            } else {
                $order = 'inputtime desc';
            }
        }

        // 获取评论数据
        $comment = $this->comment_model->get_comment_index( $this->cid, $this->index['catid']);
        if (!$comment) {
            exit($this->_msg(0, dr_lang('内容【id#%s】索引数据读取失败',  $this->cid)));
        }

        $page = max(1, (int)\Phpcmf\Service::L('input')->get('page'));
        $total = (int)\Phpcmf\Service::L('input')->get('total');

        if (IS_API_HTTP) {
            $pagesize = (int)$this->module['comment']['pagesize_api'];
        } elseif (\Phpcmf\Service::IS_MOBILE()) {
            $pagesize = (int)$this->module['comment']['pagesize_mobile'];
        } else {
            $pagesize = (int)$this->module['comment']['pagesize'];
        }

        !$pagesize && $pagesize = 10;

        // 查询数据
        list($list, $total) = $this->comment_model->get_comment_result($this->cid, $order, $page, $pagesize, $total, $this->module['comment']['field']);

        // ajax动态无刷新调用
        $js = 'dr_ajax_mform_'.$this->fid.'_comment_'. $this->cid;
        $myfield = \Phpcmf\Service::L('Field')->toform(0, $this->module['comment']['field']);

        \Phpcmf\Service::V()->assign($this->index);
        \Phpcmf\Service::V()->assign(\Phpcmf\Service::L('Seo')->comment($this->module, $this->index));
        \Phpcmf\Service::V()->assign([
            'js' => $js,
            'fid' => $this->fid,
            'type' => $type,
            'page' => $page,
            'list' => $list,
            'code' => (int)$this->module['comment']['code'],
            'index' => $this->index,
            'catid' => (int)$this->index['catid'],
            'review' => $this->module['comment']['review'],
            'emotion' => dr_comment_emotion(),
            'myfield' => $myfield,
            'comment' => $comment,
            'commnets' => $total,
            'pagesize' => $pagesize,
            'post_url' => '/index.php?s='.MOD_DIR.'&c='.$this->fid.'_comment&id='. $this->cid,
            'page_url' => '/index.php?s='.MOD_DIR.'&c='.$this->fid.'_comment&m=index&id='. $this->cid,
            'is_reply' => (int)$this->module['comment']['reply'],
            'form_name' => $this->form['name'],
            'form_table' => $this->form['table'],
            'ajax_pages' => $this->_get_pages('javascript:'.$js.'('.$type.', {page})', $total, $pagesize),
        ]);

        if (empty($_GET['callback'])) {
            \Phpcmf\Service::V()->display($this->_get_tpl($this->fid, '_comment.html'));
        } else {
            ob_start();
            \Phpcmf\Service::V()->display($this->_get_tpl($this->fid, '_comment_ajax.html'));
            $html = ob_get_contents();
            ob_clean();
            $this->_jsonp(1, $html);
        }
    }
    // 模板自身文件识别
    protected function _get_tpl($fid, $tpl) {

        $path = \Phpcmf\Service::V()->get_dir();
        if (is_file($path.$fid.$tpl)) {
            return $fid.$tpl;
        }

        return 'mform'.$tpl;
    }

    // 评论或者回复
    protected function _Post() {

        if (!IS_POST) {
            $this->_json(0, dr_lang('非法请求'));
        }

        // 挂钩点 评论完成之后
        \Phpcmf\Hooks::trigger('mform_comment_before', $this->index);

        if ($this->module['comment']['my'] && $this->index['uid'] == $this->uid) {
            // 判断不能对自己评论
            $this->_json(0, dr_lang('系统禁止对自己提交'));
        } elseif ($this->index['is_comment'] == 1) {
            // 判断内容设置的评论权限
            $this->_json(0, dr_lang('该主题禁止提交'));
        } elseif ($this->module['comment']['buy']) {
            // 购买之后才能评论
            $this->_json(0, dr_lang('请到我的订单中操作'));
        } elseif ($this->module['comment']['num'] && \Phpcmf\Service::M()->db->table($this->comment_model->mytable.'_comment')->where('cid',  $this->cid)->where('uid', $this->uid)->countAllResults()) {
            // 只允许评论一次
            $this->_json(0, dr_lang('请勿重复提交'));
        }


        if (!$this->is_hcategory) {
            // 走栏目权限
            if (!\Phpcmf\Service::M('member_auth')->mform_auth(APP_DIR, $this->fid, 'comment_add', $this->member)) {
                // 判断用户评论权限
                $this->_json(0, dr_lang('您的用户组无权限提交'));
            }
            // 评论状态
            $status = \Phpcmf\Service::M('member_auth')->mform_auth(APP_DIR, $this->fid, 'comment_verify', $this->member) ? 0 : 1;

        } else {
            // 不走栏目权限，走自定义权限
            $rt = $this->content_model->_hcategory_member_comment_auth();
            if (!$rt['code']) {
                $this->_msg(0, $rt['msg'], $rt['data']);
            }
            // 评论状态
            $status = $this->content_model->_hcategory_member_comment_status();

        }

        $rid = (int)\Phpcmf\Service::L('input')->get('rid');
        if ($rid) {
            // 判断是否回复权限
            // 禁止回复
            if (!$this->module['comment']['reply']) {
                $this->_json(0, dr_lang('系统禁止回复功能'));
            }
            // 查询主题
            $row = $this->comment_model->table($this->comment_model->mytable.'_comment')->get($rid);
            if (!$row || $this->cid != $row['cid']) {
                $this->_json(0, dr_lang('您回复的主体不存在'));
            } elseif ($row['reply']) {
                $rid = $row['reply']; // 如果他本是就是回帖内容
            } elseif ($this->module['comment']['reply'] == 2 && !(($this->member['uid'] == $row['uid'] && $row['uid'] == $this->index['uid']) || $this->member['is_admin'])) {
                // 判断仅自己
                $this->_json(0, dr_lang('您无权限回复'));
            }
        }

        // 判断会员权限
        $this->member && $this->_member_option(1);

        // 验证操作间隔
        $name = 'mform-'.$this->fid.'-comment-post-'.md5(dr_now_url().$this->uid);
        if ($this->session()->get($name)) {
            $this->_json(0, dr_lang('您动作太快了'));
        }

        // 获取评论数据
        $comment = $this->comment_model->get_comment_index( $this->cid, $this->index['catid']);
        if (!$comment) {
            $this->_json(0, dr_lang('内容【id#%s】索引数据读取失败',  $this->cid));
        }

        // 判断评论内容
        $content = $this->_safe_replace(\Phpcmf\Service::L('input')->post('content'));
        if (!$content) {
            $this->_json(0, dr_lang('%s内容不能为空', dr_comment_cname($this->module['comment']['cname'])));
        }

        // 开启点评功能时，判断各项点评数，回复不做点评
        $review = [];
        if (!$rid && $this->module['comment']['review'] && $this->module['comment']['review']['option']) {
            foreach ($this->module['comment']['review']['option'] as $i => $name) {
                $review[$i] = (int)$_POST['review'][$i];
                if (!$review[$i]) {
                    $this->_json(0, dr_lang('选项[%s]未评分', $name));
                }
            }
        }

        // 自定义字段
        if (!$rid && $this->module['comment']['field']) {
            \Phpcmf\Service::L('Field')->app(MOD_DIR);
            list($post, $return, $attach) = \Phpcmf\Service::L('Form')->validation(
                \Phpcmf\Service::L('input')->post('data'),
                [],
                $this->module['comment']['field']
            );
            // 输出错误
            if ($return) {
                $this->_json(0, $return['error']);
            }
            $my = $post[1];
        }

        // 提交评论
        $rt = $this->comment_model->insert_comment(
            [
                'index' => $this->index,
                'member' => $this->member,
                'reply_id' => $rid,
                'status' => $status,
            ],
            [
                'review' => $review,
                'content' => htmlspecialchars($content),
            ],
            $my
        );
        // 评论失败
        if (!$rt['code']) {
            $this->_json(0, $rt['msg']);
        }

        // 附件归档
        !$rid && SYS_ATTACHMENT_DB && $attach && \Phpcmf\Service::M('Attachment')->handle(
            $this->member['id'],
            \Phpcmf\Service::M()->dbprefix($this->comment_model->mytable.'_comment').'-'.$rt['code'],
            $attach
        );

        // 间隔30秒
        $this->session()->setTempdata($name, 1, 30);

        $status ? $this->_json(1, dr_lang('操作成功')) : $this->_json(1, dr_lang('操作成功，等待管理员审核'));
    }

    // 操作动作
    protected function _Op() {

        $op = \Phpcmf\Service::L('input')->get('t');
        $id = (int)\Phpcmf\Service::L('input')->get('rid');

        // 查询评论是否存在
        $data = $this->comment_model->table($this->comment_model->mytable.'_comment')->get($id);
        if (!$data) {
            $this->_json(0, dr_lang('主题不存在'));
        }

        // 获取评论索引数据
        $comment = $this->comment_model->get_comment_index( $this->cid, $this->index['catid']);
        if (!$comment) {
            $this->_msg(0, dr_lang('内容【id#%s】索引数据读取失败',  $this->cid));
        }

        // 验证操作间隔
        $name = 'mform-'.$this->fid.'-comment-op-'.md5(dr_now_url().$op.$id.$this->uid);
        if ($this->session()->get($name)) {
            $this->_json(0, dr_lang('您动作太快了'));
        }

        // 其他操作
        switch ($op) {
            case 'zc':
                $num = (int)$data['support'] + 1;
                $this->comment_model->table($this->comment_model->mytable.'_comment')->update($id, ['support' => $num]);
                $this->comment_model->table($this->comment_model->mytable.'_comment_index')->update($comment['id'], ['support' => (int)$comment['support'] + 1]);
                $this->session()->setTempdata($name, 1, 3600);
                $this->_json(1, $num);
                break;
            case 'fd':
                $num = (int)$data['oppose'] + 1;
                $this->comment_model->table($this->comment_model->mytable.'_comment')->update($id, ['oppose' => $num]);
                $this->comment_model->table($this->comment_model->mytable.'_comment_index')->update($comment['id'], ['oppose' => (int)$comment['oppose'] + 1]);
                $this->session()->setTempdata($name, 1, 3600);
                $this->_json(1, $num);
                break;

            case 'delete':
                if (!$this->uid) {
                    $this->_json(1, '无权限删除');
                } elseif (!$this->member['adminid']) {
                    $this->_json(1, '当前用户['.$this->member['username'].']无权限删除');
                }
                // 删除
                \Phpcmf\Service::M()->table($this->comment_model->mytable.'_comment')->delete($data['id']);
                \Phpcmf\Service::M('member')->delete_admin_notice(MOD_DIR.'/'.$this->fid.'_comment_verify/edit:cid/'.$data['cid'].'/id/'.$data['id'], SITE_ID);
                // 重新统计评论数
                $this->comment_model->comment_update_total($data);
                $this->comment_model->comment_update_review($data);
                $this->_json(1, '删除成功');
                break;

            default:
                $this->_json(1, '未定义的动作('.$op.')');
                break;
        }
    }

    // 格式化评论内容，方便二次开发和重写
    protected function _safe_replace($data) {
        return dr_safe_replace($data);
    }

    /**
     * 评论ajax分页 方便二次开发和重写
     */
    protected function _get_pages($url, $total, $pagesize) {

        $config = [];

        $file = 'config/page/'.(\Phpcmf\Service::IS_PC() ? 'pc' : 'mobile').'/ajax.php';
        if (is_file(WEBPATH.$file)) {
            $config = require WEBPATH.$file;
        } elseif (is_file(ROOTPATH.$file)) {
            $config = require ROOTPATH.$file;
        } else {
            $config['next_link'] = '>';
            $config['prev_link'] = '<';
            $config['last_link'] = '>|';
            $config['first_link'] = '|<';
            $config['cur_tag_open'] = '<a class="ds-current">';
            $config['cur_tag_close'] = '</a>';
        }

        $config['base_url'] = $url;
        $config['per_page'] = $pagesize;
        $config['total_rows'] = $total;
        $config['use_page_numbers'] = TRUE;
        $config['query_string_segment'] = 'page';

        return \Phpcmf\Service::L('Page')->initialize($config)->create_links();
    }


}
