<?PHP
class BackupAdmin extends Buyers
{
    protected $scanned_files = array();
    protected $exclude_dirs = array("admin/backup","cache/resize","cache/theme","admin/design/compiled");
    //включая скрытые файлы
    protected $mask = "{,.}[!.,!..]*";

    public function fetch()
    {
        // Папка для бэкапа, её же исключаем из архива
        $backup_dir = "admin/backup/";
        $dump = 'database.sql';

        if(!is_dir($this->config->root_dir . $backup_dir))
            mkdir($this->config->root_dir . $backup_dir, 0755);

        //рандомные байты для защиты от скачивания при переборе
        $filename = 'backup-'.date("d.m.Y_H-i").'-'.$this->custom->generate_name(4).'.zip';
        if($this->request->method('post'))
        {
            $action = $this->request->post('action');
            switch($action)
            {
                case 'create':
                    $path = $this->config->root_dir . $dump;
                    $this->db->dump_database($path);
                    chmod($path, 0755);

                    $files = $this->glob_recursive($this->mask);

                    $zip = new ZipArchive();
                    if($zip->open($this->config->root_dir . $backup_dir . $filename, ZipArchive::CREATE) === true)
                    {
                        foreach($files AS $file)
                            $zip->addFile($file);
                        $zip->close();
                    }
                    unlink($this->config->root_dir . $dump);

                    $status = 'created';
                break;

                case 'restore':
                    $name = $this->request->post('name');

                    $zip = new ZipArchive;
                    if($res = $zip->open($this->config->root_dir . $backup_dir . $name))
                    {
                        $zip->extractTo(getcwd());
                        $zip->close();
                    }
                    $this->db->restore($this->config->root_dir . $dump);

                    $status = 'restored';
                break;

                case 'delete':
                    $names = $this->request->post('check');
                    foreach($names as $name)
                        unlink($this->config->root_dir . $backup_dir . $name);

                    $status = 'deleted';
                break;
            }
            $this->request->redirect(array('module'=>'BackupAdmin','message_success'=>$status));
        }

        $backup_files = glob($backup_dir."*");
        $backups = array();
        if(is_array($backup_files))
        {
            foreach($backup_files as $backup_file)
            {
                $backup = new stdClass;
                $backup->name = basename($backup_file);
                $backup->size = filesize($backup_file);
                $modified = filemtime($backup_file);
                $backups[$modified] = $backup;
            }
        }
        krsort($backups);

        $this->design->assign('backup_files_dir', $backup_dir);
        if(!is_writable($backup_dir))
            $this->design->assign('message_error', 'no_permission');

        $this->design->assign('backups', $backups);

        return $this->design->fetch('backup.tpl');
    }

    protected function glob_recursive($dir)
    {
        $files = glob($dir, GLOB_BRACE);
        foreach($files as $path)
        {
            if(is_dir($path))
            {
                if(!in_array($path, $this->exclude_dirs))
                    array_merge($this->scanned_files, $this->glob_recursive($path . "/" . $this->mask));
            }
            else
                $this->scanned_files[] = $path;
        }
        return $this->scanned_files;
    }
}
