Seditio Source
Root |
./othercms/dotclear-2.22/plugins/importExport/inc/class.dc.import.flat.php
<?php
/**
 * @brief importExport, a plugin for Dotclear 2
 *
 * @package Dotclear
 * @subpackage Plugins
 *
 * @copyright Olivier Meunier & Association Dotclear
 * @copyright GPL-2.0-only
 */
if (!defined('DC_RC_PATH')) {
    return;
}

class
dcImportFlat extends dcIeModule
{
    protected
$status = false;

    public function
setInfo()
    {
       
$this->type        = 'import';
       
$this->name        = __('Flat file import');
       
$this->description = __('Imports a blog or a full Dotclear installation from flat file.');
    }

    public function
process($do)
    {
        if (
$do == 'single' || $do == 'full') {
           
$this->status = $do;

            return;
        }

       
$to_unlink = false;

       
# Single blog import
       
$files      = $this->getPublicFiles();
       
$single_upl = null;
        if (!empty(
$_POST['public_single_file']) && in_array($_POST['public_single_file'], $files)) {
           
$single_upl = false;
        } elseif (!empty(
$_FILES['up_single_file'])) {
           
$single_upl = true;
        }

        if (
$single_upl !== null) {
            if (
$single_upl) {
               
files::uploadStatus($_FILES['up_single_file']);
               
$file = DC_TPL_CACHE . '/' . md5(uniqid());
                if (!
move_uploaded_file($_FILES['up_single_file']['tmp_name'], $file)) {
                    throw new
Exception(__('Unable to move uploaded file.'));
                }
               
$to_unlink = true;
            } else {
               
$file = $_POST['public_single_file'];
            }

           
$unzip_file = '';

            try {
               
# Try to unzip file
               
$unzip_file = $this->unzip($file);
                if (
false !== $unzip_file) {
                   
$bk = new flatImport($this->core, $unzip_file);
                }
               
# Else this is a normal file
               
else {
                   
$bk = new flatImport($this->core, $file);
                }

               
$bk->importSingle();
            } catch (
Exception $e) {
                @
unlink($unzip_file);
                if (
$to_unlink) {
                    @
unlink($file);
                }

                throw
$e;
            }
            @
unlink($unzip_file);
            if (
$to_unlink) {
                @
unlink($file);
            }
           
http::redirect($this->getURL() . '&do=single');
        }

       
# Full import
       
$full_upl = null;
        if (!empty(
$_POST['public_full_file']) && in_array($_POST['public_full_file'], $files)) {
           
$full_upl = false;
        } elseif (!empty(
$_FILES['up_full_file'])) {
           
$full_upl = true;
        }

        if (
$full_upl !== null && $this->core->auth->isSuperAdmin()) {
            if (empty(
$_POST['your_pwd']) || !$this->core->auth->checkPassword($_POST['your_pwd'])) {
                throw new
Exception(__('Password verification failed'));
            }

            if (
$full_upl) {
               
files::uploadStatus($_FILES['up_full_file']);
               
$file = DC_TPL_CACHE . '/' . md5(uniqid());
                if (!
move_uploaded_file($_FILES['up_full_file']['tmp_name'], $file)) {
                    throw new
Exception(__('Unable to move uploaded file.'));
                }
               
$to_unlink = true;
            } else {
               
$file = $_POST['public_full_file'];
            }

           
$unzip_file = '';

            try {
               
# Try to unzip file
               
$unzip_file = $this->unzip($file);
                if (
false !== $unzip_file) {
                   
$bk = new flatImport($this->core, $unzip_file);
                }
               
# Else this is a normal file
               
else {
                   
$bk = new flatImport($this->core, $file);
                }

               
$bk->importFull();
            } catch (
Exception $e) {
                @
unlink($unzip_file);
                if (
$to_unlink) {
                    @
unlink($file);
                }

                throw
$e;
            }
            @
unlink($unzip_file);
            if (
$to_unlink) {
                @
unlink($file);
            }
           
http::redirect($this->getURL() . '&do=full');
        }

       
header('content-type:text/plain');
       
var_dump($_POST);
        exit;
    }

    public function
gui()
    {
        if (
$this->status == 'single') {
           
dcPage::success(__('Single blog successfully imported.'));

            return;
        }
        if (
$this->status == 'full') {
           
dcPage::success(__('Content successfully imported.'));

            return;
        }

       
$public_files = array_merge(['-' => ''], $this->getPublicFiles());
       
$has_files    = (bool) (count($public_files) - 1);

        echo
       
dcPage::jsJson(
           
'ie_import_flat_msg',
            [
'confirm_full_import' => __('Are you sure you want to import a full backup file?')]
        ) .
       
dcPage::jsModuleLoad('importExport/js/import_flat.js');
        echo
       
'<form action="' . $this->getURL(true) . '" method="post" enctype="multipart/form-data" class="fieldset">' .
       
'<h3>' . __('Single blog') . '</h3>' .
       
'<p>' . sprintf(__('This will import a single blog backup as new content in the current blog: <strong>%s</strong>.'), html::escapeHTML($this->core->blog->name)) . '</p>' .

       
'<p><label for="up_single_file">' . __('Upload a backup file') .
       
' (' . sprintf(__('maximum size %s'), files::size((int) DC_MAX_UPLOAD_SIZE)) . ')' . ' </label>' .
           
' <input type="file" id="up_single_file" name="up_single_file" size="20" />' .
           
'</p>';

        if (
$has_files) {
            echo
           
'<p><label for="public_single_file" class="">' . __('or pick up a local file in your public directory') . ' </label> ' .
           
form::combo('public_single_file', $public_files) .
               
'</p>';
        }

        echo
       
'<p>' .
       
$this->core->formNonce() .
       
form::hidden(['do'], 1) .
       
form::hidden(['MAX_FILE_SIZE'], (int) DC_MAX_UPLOAD_SIZE) .
       
'<input type="submit" value="' . __('Import') . '" /></p>' .

           
'</form>';

        if (
$this->core->auth->isSuperAdmin()) {
            echo
           
'<form action="' . $this->getURL(true) . '" method="post" enctype="multipart/form-data" id="formfull" class="fieldset">' .
           
'<h3>' . __('Multiple blogs') . '</h3>' .
           
'<p class="warning">' . __('This will reset all the content of your database, except users.') . '</p>' .

           
'<p><label for="up_full_file">' . __('Upload a backup file') . ' ' .
           
' (' . sprintf(__('maximum size %s'), files::size((int) DC_MAX_UPLOAD_SIZE)) . ')' . ' </label>' .
               
'<input type="file" id="up_full_file" name="up_full_file" size="20" />' .
               
'</p>';

            if (
$has_files) {
                echo
               
'<p><label for="public_full_file">' . __('or pick up a local file in your public directory') . ' </label>' .
               
form::combo('public_full_file', $public_files) .
                   
'</p>';
            }

            echo
           
'<p><label for="your_pwd" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Your password:') . '</label>' .
           
form::password(
               
'your_pwd',
               
20,
               
255,
                [
                   
'extra_html'   => 'required placeholder="' . __('Password') . '"',
                   
'autocomplete' => 'current-password',
                ]
            ) .
'</p>' .

           
'<p>' .
           
$this->core->formNonce() .
           
form::hidden(['do'], 1) .
           
form::hidden(['MAX_FILE_SIZE'], DC_MAX_UPLOAD_SIZE) .
           
'<input type="submit" value="' . __('Import') . '" /></p>' .

               
'</form>';
        }
    }

    protected function
getPublicFiles()
    {
       
$public_files = [];
       
$dir          = @dir($this->core->blog->public_path);
        if (
$dir) {
            while ((
$entry = $dir->read()) !== false) {
               
$entry_path = $dir->path . '/' . $entry;

                if (
is_file($entry_path) && is_readable($entry_path)) {
                   
# Do not test each zip file content here, its too long
                   
if (substr($entry_path, -4) == '.zip') {
                       
$public_files[$entry] = $entry_path;
                    } elseif (
self::checkFileContent($entry_path)) {
                       
$public_files[$entry] = $entry_path;
                    }
                }
            }
        }

        return
$public_files;
    }

    protected static function
checkFileContent($entry_path)
    {
       
$ret = false;

       
$fp  = fopen($entry_path, 'rb');
       
$ret = strpos(fgets($fp), '///DOTCLEAR|') === 0;
       
fclose($fp);

        return
$ret;
    }

    private function
unzip($file)
    {
       
$zip = new fileUnzip($file);

        if (
$zip->isEmpty()) {
           
$zip->close();

            return
false; //throw new Exception(__('File is empty or not a compressed file.'));
       
}

        foreach (
$zip->getFilesList() as $zip_file) {
           
# Check zipped file name
           
if (substr($zip_file, -4) != '.txt') {
                continue;
            }

           
# Check zipped file contents
           
$content = $zip->unzip($zip_file);
            if (
strpos($content, '///DOTCLEAR|') !== 0) {
                unset(
$content);

                continue;
            }

           
$target = path::fullFromRoot($zip_file, dirname($file));

           
# Check existing files with same name
           
if (file_exists($target)) {
               
$zip->close();
                unset(
$content);

                throw new
Exception(__('Another file with same name exists.'));
            }

           
# Extract backup content
           
if (file_put_contents($target, $content) === false) {
               
$zip->close();
                unset(
$content);

                throw new
Exception(__('Failed to extract backup file.'));
            }

           
$zip->close();
            unset(
$content);

           
# Return extracted file name
           
return $target;
        }

       
$zip->close();

        throw new
Exception(__('No backup in compressed file.'));
    }
}