<?php

namespace backend\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\helpers\ArrayHelper;
use yii\helpers\FileHelper;
use yii\db\Migration;

class DatabaseController extends BaseController
{
    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'actions' => ['index','backup','restore','dorestore','optimize','delete-restore'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                ],
            ],
        ];
    }
    public function actionIndex()
    {
        $this->check_access('database');
        $alltables  = Yii::$app->db->createCommand('SHOW TABLE STATUS')->queryAll();
        $alltables  = array_map('array_change_key_case', $alltables);
        foreach ($alltables as $key => $value) {
            if ($value['data_free']=="0") $value['data_free']="-";
            if ($value['data_free']>1 && $value['data_free']<1024) {
                $value['data_free']=$value['data_free']." byte";
            } elseif($value['data_free']>1024 && $value['data_free']<1048576) {
                $value['data_free']=number_format(($value['data_free']/1024),1)." KB";
            } elseif($value['data_free']>1048576) {
                $value['data_free']=number_format(($value['data_free']/1024/1024),1)." MB";
            }
            $value['data_length']=$value['data_length']+$value['index_length'];
            //--
            if ($value['data_length']=="0") {
                $value['data_length']="-";
            } elseif($value['data_length']<1048576) {
                $value['data_length']=number_format(($value['data_length']/1024),1)." KB";
            } elseif($value['data_length']>1048576) {
                $value['data_length']=number_format(($value['data_length']/1024/1024),1)." MB";
            }
            $alltables[$key] = $value;
        }
        return $this->render('index', [
            'list'=>$alltables,
        ]);
    }
    public function actionBackup()
    {
        $this->check_access('database');
        $tables = Yii::$app->request->get('tables');
        if(!$tables){
            $this->showmsg(0,'请选择表');
            return $this->redirect(['index']);
        }
        /* 所有数据表 */
        $alltables  = Yii::$app->db->createCommand('SHOW TABLE STATUS')->queryAll();
        $alltables  = array_map('array_change_key_case', $alltables);
        $alltables  = ArrayHelper::getColumn($alltables, 'name');
        /* 检查表是否存在 */
        foreach ($tables as $table) {
            if (!in_array($table,$alltables)) {
                $this->showmsg(0,'没有找到对应的表：'.$table);
                return $this->redirect(['index']);
            }
        }
        /* 创建migration */
        foreach ($tables as $table) {
            $migrate = Yii::createObject([
                'class' => 'e282486518\migration\components\MigrateCreate',
                'migrationPath' => '@app/migrations/'.date('Y_m_d_His')
            ]);
            $migrate->create($table);
            unset($migrate);
        }
        $this->showmsg(1,'数据备份成功！');
        return $this->redirect(['index']);
    }

    public function actionOptimize(){
        $this->check_access('database');
        $tables = Yii::$app->request->get('tables');
        if(!$tables){
            $this->showmsg(0,'请选择表');
            return $this->redirect(['index']);
        }
        /* 所有数据表 */
        $alltables  = Yii::$app->db->createCommand('SHOW TABLE STATUS')->queryAll();
        $alltables  = array_map('array_change_key_case', $alltables);
        $alltables  = ArrayHelper::getColumn($alltables, 'name');
        /* 检查表是否存在 */
        foreach ($tables as $table) {
            if (!in_array($table,$alltables)) {
                $this->showmsg(0,'没有找到对应的表：'.$table);
                return $this->redirect(['index']);
            }
        }
        foreach ($tables as $table) {
            $migrate = new Migration;
            $migrate->execute('OPTIMIZE TABLE '.$table);
            unset($migrate);
        }
        $this->showmsg(1,'数据表优化成功！');
        return $this->redirect(['index']);
    }
    public function actionRestore(){
        $path = Yii::getAlias('@app/migrations');
        $handle = opendir($path);
        $list = array();
        while (false !== ($FolderOrFile = readdir($handle))){
            if (is_dir("$path/$FolderOrFile") && $FolderOrFile != "." && $FolderOrFile != ".."){
                $arr['folder'] = $FolderOrFile;
                $arr['size'] = $this->_get_dir_size("$path/$FolderOrFile").'MB';
                $arr['addtime'] = filemtime("$path/$FolderOrFile");
                $arr['addtime'] = date('Y-m-d H:i:s',$arr['addtime']);
                $list[] = $arr;
            }
        }
        closedir($handle);
        return $this->render('restore', [
            'list'=>$list
        ]);
    }
    /**
     * 获取目录文件总大小
     */
    protected function _get_dir_size($dir,$sizeResult=0){
        $handle = opendir($dir);
        while (false !== ($FolderOrFile = readdir($handle))){
            if ($FolderOrFile != "." && $FolderOrFile != ".."){
                if (is_dir("$dir/$FolderOrFile")){
                    $sizeResult += $this->_get_dir_size("$dir/$FolderOrFile",$sizeResult);
                } else {
                    $sizeResult += filesize("$dir/$FolderOrFile");
                }
            }
        }
        closedir($handle);
        return round($sizeResult/1024/1024,2);
    }
    public function actionDorestore(){
        $this->check_access('database');
        $folder = Yii::$app->request->get('folder');
        $list = scandir(dirname(__DIR__).'/migrations/'.$folder);
        foreach ($list as $key => $value) {
            if($value!='.' && $value!='..'){
                $this->_restoreData(dirname(__DIR__).'/migrations/'.$folder.'/'.$value);
            }
        }
        $this->showmsg(1,'还原数据表成功！');
        return $this->redirect(['restore']);
    }
    public function _restoreData($file){
        require $file;
        $class_name = '\\'.$this->_getClassNameByFile($file);
        $class_name = trim($class_name,'.php');
        $class = new $class_name;
        $class->down();
        $class->up();
        unset($class);
        return true;
    }
    /**
     * 根据文件名获取备份数据类名
     */
    protected function _getClassNameByFile($path){
        return basename($path);
    }
    public function actionDeleteRestore(){
        $this->check_access('database');
        $folder = Yii::$app->request->get('folder');
        $path = Yii::getAlias('@app/migrations');
        FileHelper::removeDirectory($path.'/'.$folder);
        $this->showmsg(1,'删除数据备份成功！');
        return $this->redirect(['restore']);
    }
}
