Dotclear

source: plugins/importExport/inc/class.dc.import.flat.php @ 2485:ad130cb12ae6

Revision 2485:ad130cb12ae6, 8.5 KB checked in by Dsls, 12 years ago (diff)
  • Clear logs when importing full flat file
  • Unlink unzipped file before deleting it
  • Be more precise when raising an exception (errored line is now displayed)

Fixes #1808

RevLine 
[0]1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
[840]4# This file is part of importExport, a plugin for DotClear2.
[0]5#
[840]6# Copyright (c) 2003-2012 Olivier Meunier & Association Dotclear
[0]7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12if (!defined('DC_RC_PATH')) { return; }
13
14class dcImportFlat extends dcIeModule
15{
16     protected $status = false;
[2485]17
[0]18     public function setInfo()
19     {
[840]20          $this->type = 'import';
[0]21          $this->name = __('Flat file import');
22          $this->description = __('Imports a blog or a full Dotclear installation from flat file.');
23     }
[2485]24
[0]25     public function process($do)
26     {
27          if ($do == 'single' || $do == 'full') {
28               $this->status = $do;
29               return;
30          }
[2485]31
[0]32          $to_unlink = false;
[2485]33
[0]34          # Single blog import
35          $files = $this->getPublicFiles();
36          $single_upl = null;
37          if (!empty($_POST['public_single_file']) && in_array($_POST['public_single_file'],$files)) {
38               $single_upl = false;
39          } elseif (!empty($_FILES['up_single_file'])) {
40               $single_upl = true;
41          }
[2485]42
[0]43          if ($single_upl !== null)
44          {
45               if ($single_upl) {
46                    files::uploadStatus($_FILES['up_single_file']);
47                    $file = DC_TPL_CACHE.'/'.md5(uniqid());
48                    if (!move_uploaded_file($_FILES['up_single_file']['tmp_name'],$file)) {
49                         throw new Exception(__('Unable to move uploaded file.'));
50                    }
51                    $to_unlink = true;
52               } else {
53                    $file = $_POST['public_single_file'];
54               }
[2485]55
[0]56               try {
[840]57                    # Try to unzip file
58                    $unzip_file = $this->unzip($file);
59                    if (false !== $unzip_file) {
60                         $bk = new flatImport($this->core,$unzip_file);
61                    }
62                    # Else this is a normal file
63                    else {
64                         $bk = new flatImport($this->core,$file);
65                    }
[2485]66
[0]67                    $bk->importSingle();
68               } catch (Exception $e) {
[840]69                    @unlink($unzip_file);
[0]70                    if ($to_unlink) {
71                         @unlink($file);
72                    }
73                    throw $e;
74               }
[840]75               @unlink($unzip_file);
[0]76               if ($to_unlink) {
77                    @unlink($file);
78               }
79               http::redirect($this->getURL().'&do=single');
80          }
[2485]81
[0]82          # Full import
83          $full_upl = null;
84          if (!empty($_POST['public_full_file']) && in_array($_POST['public_full_file'],$files)) {
85               $full_upl = false;
86          } elseif (!empty($_FILES['up_full_file'])) {
87               $full_upl = true;
88          }
[2485]89
[0]90          if ($full_upl !== null && $this->core->auth->isSuperAdmin())
91          {
92               if (empty($_POST['your_pwd']) || !$this->core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) {
93                    throw new Exception(__('Password verification failed'));
94               }
[2485]95
[0]96               if ($full_upl) {
97                    files::uploadStatus($_FILES['up_full_file']);
98                    $file = DC_TPL_CACHE.'/'.md5(uniqid());
99                    if (!move_uploaded_file($_FILES['up_full_file']['tmp_name'],$file)) {
100                         throw new Exception(__('Unable to move uploaded file.'));
101                    }
102                    $to_unlink = true;
103               } else {
104                    $file = $_POST['public_full_file'];
105               }
[2485]106
[0]107               try {
[840]108                    # Try to unzip file
109                    $unzip_file = $this->unzip($file);
110                    if (false !== $unzip_file) {
111                         $bk = new flatImport($this->core,$unzip_file);
112                    }
113                    # Else this is a normal file
114                    else {
115                         $bk = new flatImport($this->core,$file);
116                    }
[2485]117
[0]118                    $bk->importFull();
119               } catch (Exception $e) {
[840]120                    @unlink($unzip_file);
[0]121                    if ($to_unlink) {
122                         @unlink($file);
123                    }
124                    throw $e;
125               }
[840]126               @unlink($unzip_file);
[0]127               if ($to_unlink) {
128                    @unlink($file);
129               }
130               http::redirect($this->getURL().'&do=full');
131          }
[2485]132
[0]133          header('content-type:text/plain');
134          var_dump($_POST);
135          exit;
[2485]136
[0]137          $this->status = true;
138     }
[2485]139
[0]140     public function gui()
141     {
142          if ($this->status == 'single')
143          {
[1559]144               dcPage::success(__('Single blog successfully imported.'));
[0]145               return;
146          }
147          if ($this->status == 'full')
148          {
[1559]149               dcPage::success(__('Content successfully imported.'));
[0]150               return;
151          }
[2485]152
[840]153          $public_files = array_merge(array('-' => ''),$this->getPublicFiles());
154          $has_files = (boolean) (count($public_files) - 1);
[2485]155
[0]156          echo
157          '<script type="text/javascript">'."\n".
158          "//<![CDATA[\n".
159          dcPage::jsVar('dotclear.msg.confirm_full_import',
160               __('Are you sure you want to import a full backup file?')).
161          "$(function() {".
162               "$('#up_single_file').change(function() { ".
163                    "if (this.value != '') { $('#public_single_file').val(''); } ".
164               "}); ".
165               "$('#public_single_file').change(function() { ".
166                    "if (this.value != '') { $('#up_single_file').val(''); } ".
167               "}); ".
168               "$('#up_full_file').change(function() { ".
169                    "if (this.value != '') { $('#public_full_file').val(''); } ".
170               "}); ".
171               "$('#public_full_file').change(function() { ".
172                    "if (this.value != '') { $('#up_full_file').val(''); } ".
173               "}); ".
174               "$('#formfull').submit(function() { ".
175                    "return window.confirm(dotclear.msg.confirm_full_import); ".
176               "}); ".
177          "});\n".
178          "//]]>\n".
179          "</script>\n";
[2485]180
[0]181          echo
[1499]182          '<form action="'.$this->getURL(true).'" method="post" enctype="multipart/form-data" class="fieldset">'.
183          '<h3>'.__('Single blog').'</h3>'.
184          '<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>'.
[2485]185
[1559]186          '<p><label for="up_single_file">'.__('Upload a backup file').
187          ' ('.sprintf(__('maximum size %s'),files::size(DC_MAX_UPLOAD_SIZE)).')'.' </label>'.
[1298]188          ' <input type="file" id="up_single_file" name="up_single_file" size="20" />'.
[557]189          '</p>';
[2485]190
[840]191          if ($has_files) {
[2485]192               echo
[1559]193               '<p><label for="public_single_file" class="">'.__('or pick up a local file in your public directory').' </label> '.
[840]194               form::combo('public_single_file',$public_files).
[1454]195               '</p>';
[840]196          }
[2485]197
198          echo
[840]199          '<p>'.
200          $this->core->formNonce().
201          form::hidden(array('do'),1).
202          form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE).
203          '<input type="submit" value="'.__('Import').'" /></p>'.
[2485]204
[0]205          '</form>';
[2485]206
[0]207          if ($this->core->auth->isSuperAdmin())
208          {
209               echo
[1499]210               '<form action="'.$this->getURL(true).'" method="post" enctype="multipart/form-data" id="formfull" class="fieldset">'.
211               '<h3>'.__('Multiple blogs').'</h3>'.
[1298]212               '<p class="warning">'.__('This will reset all the content of your database, except users.').'</p>'.
[2485]213
[1559]214               '<p><label for="up_full_file">'.__('Upload a backup file').' '.
215               ' ('.sprintf(__('maximum size %s'),files::size(DC_MAX_UPLOAD_SIZE)).')'.' </label>'.
[0]216               '<input type="file" id="up_full_file" name="up_full_file" size="20" />'.
[557]217               '</p>';
[2485]218
[840]219               if ($has_files) {
[2485]220                    echo
[1559]221                    '<p><label for="public_full_file">'.__('or pick up a local file in your public directory').' </label>'.
[840]222                    form::combo('public_full_file',$public_files).
223                    '</p>';
224               }
[2485]225
[0]226               echo
[557]227               '<p><label for="your_pwd" class="required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label>'.
228               form::password('your_pwd',20,255).'</p>'.
[2485]229
[840]230               '<p>'.
231               $this->core->formNonce().
232               form::hidden(array('do'),1).
233               form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE).
234               '<input type="submit" value="'.__('Import').'" /></p>'.
[2485]235
[0]236               '</form>';
237          }
238     }
[2485]239
[0]240     protected function getPublicFiles()
241     {
242          $public_files = array();
243          $dir = @dir($this->core->blog->public_path);
244          if ($dir)
245          {
246               while (($entry = $dir->read()) !== false) {
247                    $entry_path = $dir->path.'/'.$entry;
[2485]248
[0]249                    if (is_file($entry_path) && is_readable($entry_path))
250                    {
[840]251                         # Do not test each zip file content here, its too long
252                         if (substr($entry_path,-4) == '.zip') {
253                                   $public_files[$entry] = $entry_path;
254                         }
255                         elseif (self::checkFileContent($entry_path)) {
[0]256                              $public_files[$entry] = $entry_path;
257                         }
258                    }
259               }
260          }
261          return $public_files;
262     }
[2485]263
[840]264     protected static function checkFileContent($entry_path)
265     {
266          $ret = false;
[2485]267
[840]268          $fp = fopen($entry_path,'rb');
269          $ret = strpos(fgets($fp),'///DOTCLEAR|') === 0;
270          fclose($fp);
[2485]271
[840]272          return $ret;
273     }
[2485]274
[840]275     private function unzip($file)
276     {
277          $zip = new fileUnzip($file);
[2485]278
[840]279          if ($zip->isEmpty()) {
280               $zip->close();
281               return false;//throw new Exception(__('File is empty or not a compressed file.'));
282          }
[2485]283
[840]284          foreach($zip->getFilesList() as $zip_file)
285          {
286               # Check zipped file name
287               if (substr($zip_file,-4) != '.txt') {
288                    continue;
289               }
[2485]290
[840]291               # Check zipped file contents
292               $content = $zip->unzip($zip_file);
293               if (strpos($content,'///DOTCLEAR|') !== 0) {
294                    unset($content);
295                    continue;
296               }
[2485]297
[840]298               $target = path::fullFromRoot($zip_file,dirname($file));
[2485]299
[840]300               # Check existing files with same name
301               if (file_exists($target)) {
302                    $zip->close();
303                    unset($content);
304                    throw new Exception(__('Another file with same name exists.'));
305               }
[2485]306
[840]307               # Extract backup content
308               if (file_put_contents($target,$content) === false) {
309                    $zip->close();
310                    unset($content);
311                    throw new Exception(__('Failed to extract backup file.'));
312               }
[2485]313
[840]314               $zip->close();
315               unset($content);
[2485]316
[840]317               # Return extracted file name
318               return $target;
319          }
[2485]320
[840]321          $zip->close();
322          throw new Exception(__('No backup in compressed file.'));
323     }
[0]324}
Note: See TracBrowser for help on using the repository browser.

Sites map