Dotclear

source: plugins/importExport/inc/class.dc.import.flat.php @ 939:c79e6e87ce6e

Revision 939:c79e6e87ce6e, 8.6 KB checked in by franck <carnet.franck.paul@…>, 13 years ago (diff)

Add max file size upload limit for flat import, fixes #1232

Line 
1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of importExport, a plugin for DotClear2.
5#
6# Copyright (c) 2003-2012 Olivier Meunier & Association Dotclear
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;
17     
18     public function setInfo()
19     {
20          $this->type = 'import';
21          $this->name = __('Flat file import');
22          $this->description = __('Imports a blog or a full Dotclear installation from flat file.');
23     }
24     
25     public function process($do)
26     {
27          if ($do == 'single' || $do == 'full') {
28               $this->status = $do;
29               return;
30          }
31         
32          $to_unlink = false;
33         
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          }
42         
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               }
55               
56               try {
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                    }
66                   
67                    $bk->importSingle();
68               } catch (Exception $e) {
69                    @unlink($unzip_file);
70                    if ($to_unlink) {
71                         @unlink($file);
72                    }
73                    throw $e;
74               }
75               @unlink($unzip_file);
76               if ($to_unlink) {
77                    @unlink($file);
78               }
79               http::redirect($this->getURL().'&do=single');
80          }
81         
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          }
89         
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               }
95               
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               }
106               
107               try {
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                    }
117                   
118                    $bk->importFull();
119               } catch (Exception $e) {
120                    @unlink($unzip_file);
121                    if ($to_unlink) {
122                         @unlink($file);
123                    }
124                    throw $e;
125               }
126               @unlink($unzip_file);
127               if ($to_unlink) {
128                    @unlink($file);
129               }
130               http::redirect($this->getURL().'&do=full');
131          }
132         
133          header('content-type:text/plain');
134          var_dump($_POST);
135          exit;
136         
137          $this->status = true;
138     }
139     
140     public function gui()
141     {
142          if ($this->status == 'single')
143          {
144               dcPage::message(__('Single blog successfully imported.'));
145               return;
146          }
147          if ($this->status == 'full')
148          {
149               dcPage::message(__('Content successfully imported.'));
150               return;
151          }
152         
153          $public_files = array_merge(array('-' => ''),$this->getPublicFiles());
154          $has_files = (boolean) (count($public_files) - 1);
155         
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";
180         
181          echo
182          '<form action="'.$this->getURL(true).'" method="post" enctype="multipart/form-data">'.
183          '<fieldset><legend>'.__('Single blog').'</legend>'.
184          '<p>'.sprintf(__('This will import a single blog backup as new content in the current blog: %s.'),html::escapeHTML($this->core->blog->name)).'</p>'.
185         
186          '<p><label for="up_single_file">'.__('Upload a backup file').
187          ' ('.sprintf(__('Maximum size %s'),files::size(DC_MAX_UPLOAD_SIZE)).')'.'</label>'.
188          '<input type="file" id="up_single_file" name="up_single_file" size="20" />'.
189          '</p>';
190         
191          if ($has_files) {
192               echo 
193               '<p><label for="public_single_file">'.__('or pick up a local file in your public directory').' '.
194               form::combo('public_single_file',$public_files).
195               '</label></p>';
196          }
197         
198          echo 
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>'.
204         
205          '</fieldset>'.
206          '</form>';
207         
208          if ($this->core->auth->isSuperAdmin())
209          {
210               echo
211               '<form action="'.$this->getURL(true).'" method="post" enctype="multipart/form-data" id="formfull">'.
212               '<fieldset><legend>'.__('Multiple blogs').'</legend>'.
213               '<p>'.__('This will reset all the content of your database, except users.').'</p>'.
214               
215               '<p><label for="up_full_file">'.__('Upload a backup file').
216               ' ('.sprintf(__('Maximum size %s'),files::size(DC_MAX_UPLOAD_SIZE)).')'.'</label>'.
217               '<input type="file" id="up_full_file" name="up_full_file" size="20" />'.
218               '</p>';
219               
220               if ($has_files) {
221                    echo 
222                    '<p><label for="public_full_file">'.__('or pick up a local file in your public directory').'</label>'.
223                    form::combo('public_full_file',$public_files).
224                    '</p>';
225               }
226               
227               echo
228               '<p><label for="your_pwd" class="required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label>'.
229               form::password('your_pwd',20,255).'</p>'.
230               
231               '<p>'.
232               $this->core->formNonce().
233               form::hidden(array('do'),1).
234               form::hidden(array('MAX_FILE_SIZE'),DC_MAX_UPLOAD_SIZE).
235               '<input type="submit" value="'.__('Import').'" /></p>'.
236               
237               '</fieldset>'.
238               '</form>';
239          }
240     }
241     
242     protected function getPublicFiles()
243     {
244          $public_files = array();
245          $dir = @dir($this->core->blog->public_path);
246          if ($dir)
247          {
248               while (($entry = $dir->read()) !== false) {
249                    $entry_path = $dir->path.'/'.$entry;
250                   
251                    if (is_file($entry_path) && is_readable($entry_path))
252                    {
253                         # Do not test each zip file content here, its too long
254                         if (substr($entry_path,-4) == '.zip') {
255                                   $public_files[$entry] = $entry_path;
256                         }
257                         elseif (self::checkFileContent($entry_path)) {
258                              $public_files[$entry] = $entry_path;
259                         }
260                    }
261               }
262          }
263          return $public_files;
264     }
265     
266     protected static function checkFileContent($entry_path)
267     {
268          $ret = false;
269         
270          $fp = fopen($entry_path,'rb');
271          $ret = strpos(fgets($fp),'///DOTCLEAR|') === 0;
272          fclose($fp);
273         
274          return $ret;
275     }
276     
277     private function unzip($file)
278     {
279          $zip = new fileUnzip($file);
280         
281          if ($zip->isEmpty()) {
282               $zip->close();
283               return false;//throw new Exception(__('File is empty or not a compressed file.'));
284          }
285         
286          foreach($zip->getFilesList() as $zip_file)
287          {
288               # Check zipped file name
289               if (substr($zip_file,-4) != '.txt') {
290                    continue;
291               }
292               
293               # Check zipped file contents
294               $content = $zip->unzip($zip_file);
295               if (strpos($content,'///DOTCLEAR|') !== 0) {
296                    unset($content);
297                    continue;
298               }
299               
300               $target = path::fullFromRoot($zip_file,dirname($file));
301               
302               # Check existing files with same name
303               if (file_exists($target)) {
304                    $zip->close();
305                    unset($content);
306                    throw new Exception(__('Another file with same name exists.'));
307               }
308               
309               # Extract backup content
310               if (file_put_contents($target,$content) === false) {
311                    $zip->close();
312                    unset($content);
313                    throw new Exception(__('Failed to extract backup file.'));
314               }
315               
316               $zip->close();
317               unset($content);
318               
319               # Return extracted file name
320               return $target;
321          }
322         
323          $zip->close();
324          throw new Exception(__('No backup in compressed file.'));
325     }
326}
327?>
Note: See TracBrowser for help on using the repository browser.

Sites map