<?php

namespace PhpLife\Frame;

abstract class Controller
{
    protected $tpl; // 模板路径, 可选
    protected $queryObj;

    final public function __construct()
    {
        $this->queryObj = $this->getQuery();
    }

    /**
     * 主逻辑
     */
    final public function run()
    {
        try {
            $this->before();
            $this->checkAuth();
            $this->main();
        } catch (\Exception $ex) {
            $this->showError($ex->getCode(), $ex->getMessage());
        }
    }

    /**
     * 尽快输出结果，然后执行后续逻辑
     * 本方法的的信息不会被输出
     * 即使exit之后仍旧能被执行
     */
    final public function __destruct()
    {
        if (function_exists('fastcgi_finish_request')) {
            fastcgi_finish_request();
        }
        $this->after();
    }

    /**
     * 前置方法，处理参数
     */
    protected function before()
    {

    }

    /**
     * 执行验证
     */
    protected function checkAuth()
    {

    }

    /**
     * 执行逻辑
     * @return mixed
     */
    protected abstract function main();

    /**
     * 后续方法
     */
    protected function after()
    {

    }

    /**
     * 显示错误信息
     * @param int $code
     * @param string $message
     */
    protected function showError($code = 0, $message = '')
    {
        echo "[$code] $message \n<br>";
        exit;
    }

    /**
     * @return Filter
     */
    protected function getRequest()
    {
        static $instance = null;
        if (is_null($instance)) {
            $instance = new Filter($_REQUEST);
        }
        return $instance;
    }

    /**
     * @return Filter
     */
    protected function getQuery()
    {
        static $instance = null;
        if (is_null($instance)) {
            $instance = new Filter($_GET);
        }
        return $instance;
    }

    /**
     * @return Filter
     */
    protected function getPost()
    {
        static $instance = null;
        if (is_null($instance)) {
            $instance = new Filter($_POST);
        }
        return $instance;
    }

    /**
     * 获取模板, 固定模板, 与controller名称类似
     * @return \PhpLife\Frame\Template
     */
    protected function getTemplate()
    {
        static $template;
        if ($template) {
            return $template;
        }
        $class = get_called_class();
        $class = explode('\\', $class);
        $path = dirname(__DIR__) . '/' . implode('/', array_slice($class, 1, 2)) . '/Template/';
        if(!$this->tpl){
            $this->tpl = implode('/', array_slice($class, 4));
        }
        $template = new Template();
        $template->setPath($path)->setTpl($this->tpl);
        $data = get_object_vars($this);
        if ($data) {
            $template->assign($data);
        }
        return $template;
    }

    /**
     * 检查CSRF攻击
     * @return bool
     */
    protected function checkCsrf()
    {
        $host = strtolower(trim($_SERVER['HTTP_HOST']));
        $referer = parse_url($_SERVER['HTTP_REFERER']);
        $referer = substr(strtolower(trim($referer['host'])), -(strlen($host)));
        if (!empty($referer) AND $referer != $host AND $referer != ('www.' . $host)) {
            return false;
        }
        return true;
    }

}
