<?php
/*
 *   $Id$
 *
 *   AbanteCart, Ideal OpenSource Ecommerce Solution
 *   http://www.AbanteCart.com
 *
 *   Copyright © 2011-2024 Belavier Commerce LLC
 *
 *   This source file is subject to Open Software License (OSL 3.0)
 *   License details is bundled with this package in the file LICENSE.txt.
 *   It is also available at this URL:
 *   <http://www.opensource.org/licenses/OSL-3.0>
 *
 *  UPGRADE NOTE:
 *    Do not edit or add to this file if you wish to upgrade AbanteCart to newer
 *    versions in the future. If you wish to customize AbanteCart for your
 *    needs please refer to http://www.AbanteCart.com for more information.
 */
if (!defined('DIR_CORE') || !IS_ADMIN) {
    header('Location: static_pages/');
}

if (defined('IS_DEMO') && IS_DEMO) {
    header('Location: static_pages/demo_mode.php');
}

class ControllerPagesToolBackup extends AController
{
    public $error = [];

    public function main()
    {

        //init controller data
        $this->extensions->hk_InitData($this, __FUNCTION__);

        $this->loadLanguage('tool/backup');
        $this->loadModel('tool/backup');

        $this->document->setTitle($this->language->get('heading_title'));
        //schedule task for backup
        if ($this->request->is_POST() && $this->_validate()) {
            $file_type = '';
            if (is_uploaded_file($this->request->files['restore']['tmp_name'])) {
                if (pathinfo($this->request->files['restore']['name'], PATHINFO_EXTENSION) == 'sql') {
                    $file_type = 'sql';
                    $content = file_get_contents($this->request->files['restore']['tmp_name']);
                } else {
                    $content = false;
                }
            } elseif (is_uploaded_file($this->request->files['import']['tmp_name'])) {
                if (pathinfo($this->request->files['import']['name'], PATHINFO_EXTENSION) == 'xml') {
                    $file_type = 'xml';
                    $content = file_get_contents($this->request->files['import']['tmp_name']);
                } else {
                    $content = false;
                }
            } else {
                $content = false;
                //create schedule task for backup
                $task_details = $this->model_tool_backup->createBackupTask('scheduled_backup', $this->request->post);
                if (!$task_details) {
                    $this->error['warning'] = array_merge($this->error, $this->model_tool_backup->errors);
                } else {
                    $this->session->data['success'] = sprintf(
                        $this->language->get('text_success_scheduled'),
                        $this->html->getSecureURL('tool/task')
                    );
                    redirect($this->html->getSecureURL('tool/backup'));
                }

            }

            if ($content) {
                $this->cache->remove('*');
                if ($file_type == 'sql') {
                    $this->model_tool_backup->restore($content);
                    $this->session->data['success'] = $this->language->get('text_success');
                    redirect($this->html->getSecureURL('tool/backup'));
                } else {
                    if ($this->model_tool_backup->load($content)) {
                        $this->session->data['success'] = $this->language->get('text_success_xml');
                        redirect($this->html->getSecureURL('tool/backup'));
                    } else {
                        $this->error['warning'] = $this->language->get('error_xml');
                    }
                }
            } elseif (!has_value($this->request->post['do_backup'])) {
                if ($this->request->files) {
                    $this->error['warning'] = $this->language->get('error_empty')
                        . ' (' . pathinfo($this->request->files['restore']['name'], PATHINFO_EXTENSION) . ')';
                } else {
                    $this->error['warning'] = $this->language->get('error_upload');
                    $uploaded_file = '';
                    if (isset($this->request->files['restore'])) {
                        $uploaded_file = $this->request->files['restore'];
                    } elseif ($this->request->files['import']) {
                        $uploaded_file = $this->request->files['import'];
                    }
                    if ($uploaded_file) {
                        $this->error['warning'] .= '<br>Error: ' . getTextUploadError($uploaded_file['error']);
                    }
                }
            }
        }

        if (isset($this->error['warning'])) {
            $this->data['error_warning'] = $this->error['warning'];
        } elseif ($this->session->data['error']) {
            $this->data['error_warning'] = $this->session->data['error'];
            unset($this->session->data['error']);
        } else {
            $bkp = new ABackup('manual_backup');
            $bkp->validate();
            $this->data['error_warning'] = implode("\n", $bkp->error);
            $bkp->removeBackupDirectory();
        }

        if (isset($this->session->data['success'])) {
            $this->data['success'] = $this->session->data['success'];
            unset($this->session->data['success']);
        } else {
            $this->data['success'] = '';
        }

        $this->document->resetBreadcrumbs();

        $this->document->addBreadcrumb(
            [
                'href'      => $this->html->getSecureURL('index/home'),
                'text'      => $this->language->get('text_home'),
                'separator' => false,
            ]
        );

        $this->document->addBreadcrumb(
            [
                'href'      => $this->html->getSecureURL('tool/backup'),
                'text'      => $this->language->get('heading_title'),
                'separator' => ' :: ',
                'current'   => true,
            ]
        );

        $this->loadModel('tool/backup');

        $this->data['tables'] = $this->model_tool_backup->getTables();
        //if we cannot to get table list from database -show error
        if ($this->data['tables'] === false) {
            $this->data['tables'] = [];
        }

        $table_sizes = $this->model_tool_backup->getTableSizes($this->data['tables']);
        $tables = [];
        $db_size = 0;
        foreach ($this->data['tables'] as $table) {
            $tables[$table] = $table . ' (' . $table_sizes[$table]['text'] . ')';
            $db_size += $table_sizes[$table]['bytes'];
        }
        //size of data of database (sql-file will be greater)
        if ($db_size > 1048576) {
            $this->data['entry_tables_size'] = round(($db_size / 1048576), 1) . 'Mb';
        } else {
            $this->data['entry_tables_size'] = round($db_size / 1024, 1) . 'Kb';
        }

        $form = new AForm('ST');

        $form->setForm(['form_name' => 'backup']);

        $this->data['form']['id'] = 'backup';
        $this->data['form']['form_open'] = $form->getFieldHtml(
                [
                    'type'    => 'form',
                    'name'    => 'backup',
                    'action'  => $this->html->getSecureURL('tool/backup'),
                    'attr'    => 'class="aform form-horizontal"',
                    'enctype' => 'multipart/form-data'
                ]
            ) .
            $form->getFieldHtml(
                [
                    'type'  => 'hidden',
                    'name'  => 'do_backup',
                    'value' => 1,
                ]
            );

        $this->data['form']['fields']['tables'] = $form->getFieldHtml(
            [
                'type'      => 'checkboxgroup',
                'name'      => 'table_list[]',
                'value'     => $this->data['tables'],
                'options'   => $tables,
                'scrollbox' => true,
                'style'     => 'checkboxgroup',
            ]
        );

        $c_size = $this->model_tool_backup->getCodeSize();
        if ($c_size > 1048576) {
            $code_size = round(($c_size / 1048576), 1) . 'Mb';
        } else {
            $code_size = round(($c_size / 1024), 1) . 'Kb';
        }
        $this->data['entry_backup_code'] = sprintf($this->language->get('entry_backup_code'), $code_size);

        $this->data['form']['fields']['backup_code'] = $form->getFieldHtml(
            [
                'type'    => 'checkbox',
                'name'    => 'backup_code',
                'value'   => '1',
                'checked' => true,
            ]
        );

        $c_size = $this->model_tool_backup->getContentSize();
        if ($c_size > 1048576) {
            $content_size = round(($c_size / 1048576), 1) . 'Mb';
        } else {
            $content_size = round(($c_size / 1024), 1) . 'Kb';
        }
        $this->data['entry_backup_content'] = sprintf($this->language->get('entry_backup_content'), $content_size);

        $this->data['form']['fields']['backup_content'] = $form->getFieldHtml(
            [
                'type'    => 'checkbox',
                'name'    => 'backup_content',
                'value'   => '1',
                'checked' => true,
            ]
        );

        $this->data['form']['fields']['compress_backup'] = $form->getFieldHtml(
            [
                'type'  => 'checkbox',
                'name'  => 'compress_backup',
                'value' => 1,
            ]
        );

        $this->data['entry_compress_backup'] = sprintf(
            $this->language->get('entry_compress_backup'),
            str_replace(DIR_ROOT, '', DIR_BACKUP),
            str_replace(DIR_ROOT . '/', '', DIR_BACKUP)
        );

        $this->data['form']['build_task_url'] = $this->html->getSecureURL('r/tool/backup/buildTask');
        $this->data['form']['complete_task_url'] = $this->html->getSecureURL('r/tool/backup/complete');
        $this->data['form']['backup_now'] = $form->getFieldHtml(
            [
                'type'  => 'button',
                'name'  => 'backup_now',
                'text'  => $this->language->get('button_backup_now'),
                'style' => 'button1',
            ]
        );
        $this->data['form']['backup_schedule'] = $form->getFieldHtml(
            [
                'type'  => 'button',
                'name'  => 'backup_schedule',
                'text'  => $this->language->get('button_backup_schedule'),
                'style' => 'button1',
            ]
        );

        $form = new AForm('ST');
        $form->setForm(['form_name' => 'restore_form']);
        $this->data['restoreform']['id'] = 'restore_form';
        $this->data['restoreform']['form_open'] = $form->getFieldHtml(
            [
                'type'    => 'form',
                'name'    => 'restore_form',
                'action'  => $this->html->getSecureURL('tool/backup'),
                'attr'    => 'class="aform form-horizontal"',
                'enctype' => 'multipart/form-data'
            ]
        );
        $this->data['restoreform']['file'] = $form->getFieldHtml(
            [
                'type' => 'file',
                'name' => 'restore',
                'attr' => 'accept=".sql, .xml"',
            ]
        );
        $this->data['restoreform']['submit'] = $form->getFieldHtml(
            [
                'type'  => 'button',
                'name'  => 'submit',
                'text'  => $this->language->get('tab_restore'),
                'style' => 'button1',
            ]
        );

        $form = new AForm('ST');
        $form->setForm(['form_name' => 'loadxml_form']);
        $this->data['xmlform']['id'] = 'loadxml_form';
        $this->data['xmlform']['form_open'] = $form->getFieldHtml(
            [
                'type'    => 'form',
                'name'    => 'loadxml_form',
                'action'  => $this->html->getSecureURL('tool/backup'),
                'attr'    => 'class="aform form-horizontal"',
                'enctype' => 'multipart/form-data'
            ]
        );
        $this->data['xmlform']['file'] = $form->getFieldHtml(
            [
                'type' => 'file',
                'name' => 'import',
                'attr' => 'accept=".xml"',
            ]
        );
        $this->data['xmlform']['submit'] = $form->getFieldHtml(
            [
                'type'  => 'button',
                'name'  => 'submit',
                'text'  => $this->language->get('button_load'),
                'style' => 'button1',
            ]
        );

        $this->data['text_fail_note'] = sprintf($this->language->get('text_fail_note'), DIR_APP_SECTION . 'system/backup');

        $this->view->batchAssign($this->data);
        $this->view->assign('help_url', $this->gen_help_url());
        $this->view->assign('current_url', $this->html->currentURL());

        $this->processTemplate('pages/tool/backup.tpl');

        //update controller data
        $this->extensions->hk_UpdateData($this, __FUNCTION__);

    }

    private function _validate()
    {
        if (!$this->user->canModify('tool/backup')) {
            $this->error['warning'] = $this->language->get('error_permission');
        }

        foreach ($this->request->files as $k => $file) {
            if ($file['size'] == 0) {
                unset($this->request->files[$k]);
            }
        }

        if (!$this->request->post && !$this->request->files) {
            $this->error['warning'] = $this->language->get('error_nothing_to_do');
        }

        if (has_value($this->request->post['do_backup'])) { // sign of backup form
            $this->request->post['backup_code'] = (bool)$this->request->post['backup_code'];
            $this->request->post['backup_content'] = (bool)$this->request->post['backup_content'];

            if (!$this->request->post['do_backup']
                && !$this->request->post['backup_code']
                && !$this->request->post['backup_content']
            ) {
                $this->error['warning'] = $this->language->get('error_nothing_to_backup');
            }
        }
        return (!$this->error);
    }

    public function download()
    {
        //init controller data
        $this->extensions->hk_InitData($this, __FUNCTION__);

        if ($this->user->canAccess('tool/backup')) {
            $filename = str_replace(['../', '..\\', '\\', '/'], '', $this->request->get['filename']);
            $file = DIR_BACKUP . $filename;
            if (file_exists($file)) {
                header('Content-Description: File Transfer');
                header('Content-Type: application/x-gzip');
                header('Content-Disposition: attachment; filename=' . $filename);
                header('Content-Transfer-Encoding: binary');
                header('Expires: 0');
                header('Cache-Control: must-revalidate');
                header('Pragma: public');
                header('Content-Length: ' . filesize($file));
                ob_end_clean();
                flush();
                readfile($file);
                exit;
            } else {
                $this->session->data['error'] = 'Error: You Cannot to Download File ' . $file . ' Because of Absent on Hard Drive.';
                redirect($this->html->getSecureURL('tool/install_upgrade_history'));
            }
        } else {
            $this->dispatch('error/permission');
        }
    }
}