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']; } 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']; } 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; $this->status = true; } 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 = (boolean) (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::jsLoad(dcPage::getPF('importExport/js/import_flat.js')); echo '
' . '

' . __('Single blog') . '

' . '

' . sprintf(__('This will import a single blog backup as new content in the current blog: %s.'), html::escapeHTML($this->core->blog->name)) . '

' . '

' . ' ' . '

'; if ($has_files) { echo '

' . form::combo('public_single_file', $public_files) . '

'; } echo '

' . $this->core->formNonce() . form::hidden(['do'], 1) . form::hidden(['MAX_FILE_SIZE'], DC_MAX_UPLOAD_SIZE) . '

' . '
'; if ($this->core->auth->isSuperAdmin()) { echo '
' . '

' . __('Multiple blogs') . '

' . '

' . __('This will reset all the content of your database, except users.') . '

' . '

' . '' . '

'; if ($has_files) { echo '

' . form::combo('public_full_file', $public_files) . '

'; } echo '

' . form::password('your_pwd', 20, 255, [ 'extra_html' => 'required placeholder="' . __('Password') . '"', 'autocomplete' => 'current-password' ] ) . '

' . '

' . $this->core->formNonce() . form::hidden(['do'], 1) . form::hidden(['MAX_FILE_SIZE'], DC_MAX_UPLOAD_SIZE) . '

' . '
'; } } 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.')); } }