Dotclear

source: plugins/importExport/inc/class.dc.import.dc1.php @ 1569:a643401a714a

Revision 1569:a643401a714a, 17.1 KB checked in by Anne Kozlika <kozlika@…>, 11 years ago (diff)

Form-notes and contextual alerts don't need to be 100% wide.

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 dcImportDC1 extends dcIeModule
15{
16     protected $con;
17     protected $prefix;
18     protected $blog_id;
19     
20     protected $action = null;
21     protected $step = 1;
22     
23     protected $post_offset = 0;
24     protected $post_limit = 20;
25     protected $post_count = 0;
26     
27     protected $has_table = array();
28     
29     protected $vars;
30     protected $base_vars = array(
31          'db_host' => '',
32          'db_name' => '',
33          'db_user' => '',
34          'db_pwd' => '',
35          'db_prefix' => 'dc_',
36          'post_limit' => 20,
37          'cat_ids' => array()
38     );
39     
40     protected function setInfo()
41     {
42          $this->type = 'import';
43          $this->name = __('Dotclear 1.2 import');
44          $this->description = __('Import a Dotclear 1.2 installation into your current blog.');
45     }
46     
47     public function init()
48     {
49          $this->con =& $this->core->con;
50          $this->prefix = $this->core->prefix;
51          $this->blog_id = $this->core->blog->id;
52         
53          if (!isset($_SESSION['dc1_import_vars'])) {
54               $_SESSION['dc1_import_vars'] = $this->base_vars;
55          }
56          $this->vars =& $_SESSION['dc1_import_vars'];
57         
58          if ($this->vars['post_limit'] > 0) {
59               $this->post_limit = $this->vars['post_limit'];
60          }
61     }
62     
63     public function resetVars()
64     {
65          $this->vars = $this->base_vars;;
66          unset($_SESSION['dc1_import_vars']);
67     }
68     
69     public function process($do)
70     {
71          $this->action = $do;
72     }
73     
74     # We handle process in another way to always display something to
75     # user
76     protected function guiprocess($do)
77     {
78          switch ($do)
79          {
80               case 'step1':
81                    $this->vars['db_host'] = $_POST['db_host'];
82                    $this->vars['db_name'] = $_POST['db_name'];
83                    $this->vars['db_user'] = $_POST['db_user'];
84                    $this->vars['db_pwd'] = $_POST['db_pwd'];
85                    $this->vars['post_limit'] = abs((integer) $_POST['post_limit']) > 0 ? $_POST['post_limit'] : 0;
86                    $this->vars['db_prefix'] = $_POST['db_prefix'];
87                    $db = $this->db();
88                    $db->close();
89                    $this->step = 2;
90                    echo $this->progressBar(1);
91                    break;
92               case 'step2':
93                    $this->step = 2;
94                    $this->importUsers();
95                    $this->step = 3;
96                    echo $this->progressBar(3);
97                    break;
98               case 'step3':
99                    $this->step = 3;
100                    $this->importCategories();
101                    if ($this->core->plugins->moduleExists('blogroll')) {
102                         $this->step = 4;
103                         echo $this->progressBar(5);
104                    } else {
105                         $this->step = 5;
106                         echo $this->progressBar(7);
107                    }
108                    break;
109               case 'step4':
110                    $this->step = 4;
111                    $this->importLinks();
112                    $this->step = 5;
113                    echo $this->progressBar(7);
114                    break;
115               case 'step5':
116                    $this->step = 5;
117                    $this->post_offset = !empty($_REQUEST['offset']) ? abs((integer) $_REQUEST['offset']) : 0;
118                    if ($this->importPosts($percent) === -1) {
119                         http::redirect($this->getURL().'&do=ok');
120                    } else {
121                         echo $this->progressBar(ceil($percent*0.93)+7);
122                    }
123                    break;
124               case 'ok':
125                    $this->resetVars();
126                    $this->core->blog->triggerBlog();
127                    $this->step = 6;
128                    echo $this->progressBar(100);
129                    break;
130          }
131     }
132     
133     public function gui()
134     {
135          try {
136               $this->guiprocess($this->action);
137          } catch (Exception $e) {
138               $this->error($e);
139          }
140         
141          switch ($this->step)
142          {
143               case 1:
144                    echo
145                    '<p>'.sprintf(__('Import the content of a Dotclear 1.2\'s blog in the current blog: %s.'),
146                    '<strong>'.html::escapeHTML($this->core->blog->name).'</strong>').'</p>'.
147                    '<p class="warning">'.__('Please note that this process '.
148                    'will empty your categories, blogroll, entries and comments on the current blog.').'</p>';
149                   
150                    printf($this->imForm(1,__('General information'),__('Import my blog now')),
151                    '<p>'.__('We first need some information about your old Dotclear 1.2 installation.').'</p>'.
152                    '<p><label for="db_host">'.__('Database Host Name:').'</label> '.
153                    form::field('db_host',30,255,html::escapeHTML($this->vars['db_host'])).'</p>'.
154                    '<p><label for="db_name">'.__('Database Name:',html::escapeHTML($this->vars['db_name'])).'</label> '.
155                    form::field('db_name',30,255,html::escapeHTML($this->vars['db_name'])).'</p>'.
156                    '<p><label for="db_user">'.__('Database User Name:').'</label> '.
157                    form::field('db_user',30,255,html::escapeHTML($this->vars['db_user'])).'</p>'.
158                    '<p><label for="db_pwd">'.__('Database Password:').'</label> '.
159                    form::password('db_pwd',30,255).'</p>'.
160                    '<p><label for="db_prefix">'.__('Database Tables Prefix:').'</label> '.
161                    form::field('db_prefix',30,255,html::escapeHTML($this->vars['db_prefix'])).'</p>'.
162                    '<h3>'.__('Entries import options').'</h3>'.
163                    '<p><label for="post_limit">'.__('Number of entries to import at once:').'</label> '.
164                    form::field('post_limit',3,3,html::escapeHTML($this->vars['post_limit'])).'</p>'
165                    );
166                    break;
167               case 2:
168                    printf($this->imForm(2,__('Importing users')),
169                         $this->autoSubmit()
170                    );
171                    break;
172               case 3:
173                    printf($this->imForm(3,__('Importing categories')),
174                         $this->autoSubmit()
175                    );
176                    break;
177               case 4:
178                    printf($this->imForm(4,__('Importing blogroll')),
179                         $this->autoSubmit()
180                    );
181                    break;
182               case 5:
183                    $t = sprintf(__('Importing entries from %d to %d / %d'),$this->post_offset,
184                         min(array($this->post_offset+$this->post_limit,$this->post_count)),$this->post_count);
185                    printf($this->imForm(5,$t),
186                         form::hidden(array('offset'),$this->post_offset).
187                         $this->autoSubmit()
188                    );
189                    break;
190               case 6:
191                    echo 
192                    '<h3>'.__('Please read carefully').'</h3>'.
193                    '<ul>'.
194                    '<li>'.__('Every newly imported user has received a random password '.
195                    'and will need to ask for a new one by following the "I forgot my password" link on the login page '.
196                    '(Their registered email address has to be valid.)').'</li>'.
197                   
198                    '<li>'.sprintf(__('Please note that Dotclear 2 has a new URL layout. You can avoid broken '.
199                    'links by installing <a href="%s">DC1 redirect</a> plugin and activate it in your blog configuration.'),
200                    'http://plugins.dotaddict.org/dc2/details/dc1redirect').'</li>'.
201                    '</ul>'.
202                   
203                    $this->congratMessage();
204                   
205                    break;
206          }
207     }
208     
209     # Simple form for step by step process
210     protected function imForm($step,$legend,$submit_value=null)
211     {
212          if (!$submit_value) {
213               $submit_value = __('next step').' >';
214          }
215         
216          return
217          '<form action="'.$this->getURL(true).'" method="post">'.
218          '<h3>'.$legend.'</h3>'.
219          $this->core->formNonce().
220          form::hidden(array('do'),'step'.$step).
221          '%s'.
222          '<p><input type="submit" value="'.$submit_value.'" /></p>'.
223          '<p class="form-note info">'.__('Depending on the size of your blog, it could take a few minutes.').'</p>'.
224          '</form>';
225     }
226     
227     # Error display
228     protected function error($e)
229     {
230          echo '<div class="error"><strong>'.__('Errors:').'</strong>'.
231          '<p>'.$e->getMessage().'</p></div>';
232     }
233     
234     # Database init
235     protected function db()
236     {
237          $db = dbLayer::init('mysql',$this->vars['db_host'],$this->vars['db_name'],$this->vars['db_user'],$this->vars['db_pwd']);
238         
239          $rs = $db->select("SHOW TABLES LIKE '".$this->vars['db_prefix']."%'");
240          if ($rs->isEmpty()) {
241               throw new Exception(__('Dotclear tables not found'));
242          }
243         
244          while ($rs->fetch()) {
245               $this->has_table[$rs->f(0)] = true;
246          }
247         
248          # Set this to read data as they were written in Dotclear 1
249          try {
250               $db->execute('SET NAMES DEFAULT');
251          } catch (Exception $e) {}
252         
253          $db->execute('SET CHARACTER SET DEFAULT');
254          $db->execute("SET COLLATION_CONNECTION = DEFAULT");
255          $db->execute("SET COLLATION_SERVER = DEFAULT");
256          $db->execute("SET CHARACTER_SET_SERVER = DEFAULT");
257          $db->execute("SET CHARACTER_SET_DATABASE = DEFAULT");
258         
259          $this->post_count = $db->select(
260               'SELECT COUNT(post_id) FROM '.$this->vars['db_prefix'].'post '
261          )->f(0);
262         
263          return $db;
264     }
265     
266     protected function cleanStr($str)
267     {
268          return text::cleanUTF8(@text::toUTF8($str));
269     }
270     
271     # Users import
272     protected function importUsers()
273     {
274          $db = $this->db();
275          $prefix = $this->vars['db_prefix'];
276          $rs = $db->select('SELECT * FROM '.$prefix.'user');
277         
278          try
279          {
280               $this->con->begin();
281               
282               while ($rs->fetch())
283               {
284                    if (!$this->core->userExists($rs->user_id))
285                    {
286                         $cur = $this->con->openCursor($this->prefix.'user');
287                         $cur->user_id          = $rs->user_id;
288                         $cur->user_name        = $rs->user_nom;
289                         $cur->user_firstname   = $rs->user_prenom;
290                         $cur->user_displayname = $rs->user_pseudo;
291                         $cur->user_pwd         = crypt::createPassword();
292                         $cur->user_email       = $rs->user_email;
293                         $cur->user_lang        = $rs->user_lang;
294                         $cur->user_tz          = $this->core->blog->settings->system->blog_timezone;
295                         $cur->user_post_status = $rs->user_post_pub ? 1 : -2;
296                         $cur->user_options     = new ArrayObject(array(
297                              'edit_size' => (integer) $rs->user_edit_size,
298                              'post_format' => $rs->user_post_format
299                         ));
300                         
301                         $permissions = array();
302                         switch ($rs->user_level)
303                         {
304                              case '0':
305                                   $cur->user_status = 0;
306                                   break;
307                              case '1': # editor
308                                   $permissions['usage'] = true;
309                                   break;
310                              case '5': # advanced editor
311                                   $permissions['contentadmin'] = true;
312                                   $permissions['categories'] = true;
313                                   $permissions['media_admin'] = true;
314                                   break;
315                              case '9': # admin
316                                   $permissions['admin'] = true;
317                                   break;
318                         }
319                         
320                         $this->core->addUser($cur);
321                         $this->core->setUserBlogPermissions(
322                              $rs->user_id,
323                              $this->blog_id,
324                              $permissions
325                         );
326                    }
327               }
328               
329               $this->con->commit();
330               $db->close();
331          }
332          catch (Exception $e)
333          {
334               $this->con->rollback();
335               $db->close();
336               throw $e;
337          }
338     }
339     
340     # Categories import
341     protected function importCategories()
342     {
343          $db = $this->db();
344          $prefix = $this->vars['db_prefix'];
345          $rs = $db->select('SELECT * FROM '.$prefix.'categorie ORDER BY cat_ord ASC');
346         
347          try
348          {
349               $this->con->execute(
350                    'DELETE FROM '.$this->prefix.'category '.
351                    "WHERE blog_id = '".$this->con->escape($this->blog_id)."' "
352               );
353               
354               $ord = 2;
355               while ($rs->fetch())
356               {
357                    $cur = $this->con->openCursor($this->prefix.'category');
358                    $cur->blog_id      = $this->blog_id;
359                    $cur->cat_title    = $this->cleanStr(htmlspecialchars_decode($rs->cat_libelle));
360                    $cur->cat_desc     = $this->cleanStr($rs->cat_desc);
361                    $cur->cat_url      = $this->cleanStr($rs->cat_libelle_url);
362                    $cur->cat_lft      = $ord++;
363                    $cur->cat_rgt      = $ord++;
364                   
365                    $cur->cat_id = $this->con->select(
366                         'SELECT MAX(cat_id) FROM '.$this->prefix.'category'
367                         )->f(0) + 1;
368                    $this->vars['cat_ids'][$rs->cat_id] = $cur->cat_id;
369                    $cur->insert();
370               }
371               
372               $db->close();
373          }
374          catch (Exception $e)
375          {
376               $db->close();
377               throw $e;
378          }
379     }
380     
381     # Blogroll import
382     protected function importLinks()
383     {
384          $db = $this->db();
385          $prefix = $this->vars['db_prefix'];
386          $rs = $db->select('SELECT * FROM '.$prefix.'link ORDER BY link_id ASC');
387         
388          try
389          {
390               $this->con->execute(
391                    'DELETE FROM '.$this->prefix.'link '.
392                    "WHERE blog_id = '".$this->con->escape($this->blog_id)."' "
393               );
394               
395               while ($rs->fetch())
396               {
397                    $cur = $this->con->openCursor($this->prefix.'link');
398                    $cur->blog_id       = $this->blog_id;
399                    $cur->link_href     = $this->cleanStr($rs->href);
400                    $cur->link_title    = $this->cleanStr($rs->label);
401                    $cur->link_desc     = $this->cleanStr($rs->title);
402                    $cur->link_lang     = $this->cleanStr($rs->lang);
403                    $cur->link_xfn      = $this->cleanStr($rs->rel);
404                    $cur->link_position = (integer) $rs->position;
405                   
406                    $cur->link_id = $this->con->select(
407                         'SELECT MAX(link_id) FROM '.$this->prefix.'link'
408                         )->f(0) + 1;
409                    $cur->insert();
410               }
411               
412               $db->close();
413          }
414          catch (Exception $e)
415          {
416               $db->close();
417               throw $e;
418          }
419     }
420     
421     # Entries import
422     protected function importPosts(&$percent)
423     {
424          $db = $this->db();
425          $prefix = $this->vars['db_prefix'];
426         
427          $count = $db->select('SELECT COUNT(post_id) FROM '.$prefix.'post')->f(0);
428         
429          $rs = $db->select(
430               'SELECT * FROM '.$prefix.'post ORDER BY post_id ASC '.
431               $db->limit($this->post_offset,$this->post_limit)
432          );
433         
434          try
435          {
436               if ($this->post_offset == 0)
437               {
438                    $this->con->execute(
439                         'DELETE FROM '.$this->prefix.'post '.
440                         "WHERE blog_id = '".$this->con->escape($this->blog_id)."' "
441                    );
442               }
443               
444               while ($rs->fetch()) {
445                    $this->importPost($rs,$db);
446               }
447               
448               $db->close();
449          }
450          catch (Exception $e)
451          {
452               $db->close();
453               throw $e;
454          }
455         
456          if ($rs->count() < $this->post_limit) {
457               return -1;
458          } else {
459               $this->post_offset += $this->post_limit;
460          }
461         
462          if ($this->post_offset > $this->post_count) {
463               $percent = 100;
464          } else {
465               $percent = $this->post_offset * 100 / $this->post_count;
466          }
467     }
468     
469     protected function importPost($rs,$db)
470     {
471          $cur = $this->con->openCursor($this->prefix.'post');
472          $cur->blog_id     = $this->blog_id;
473          $cur->user_id     = $rs->user_id;
474          $cur->cat_id      = (integer) $this->vars['cat_ids'][$rs->cat_id];
475          $cur->post_dt     = $rs->post_dt;
476          $cur->post_creadt = $rs->post_creadt;
477          $cur->post_upddt  = $rs->post_upddt;
478          $cur->post_title  = html::decodeEntities($this->cleanStr($rs->post_titre));
479         
480          $cur->post_url = date('Y/m/d/',strtotime($cur->post_dt)).$rs->post_id.'-'.$rs->post_titre_url;
481          $cur->post_url = substr($cur->post_url,0,255);
482         
483          $cur->post_format        = $rs->post_content_wiki == '' ? 'xhtml' : 'wiki';
484          $cur->post_content_xhtml = $this->cleanStr($rs->post_content);
485          $cur->post_excerpt_xhtml = $this->cleanStr($rs->post_chapo);
486         
487          if ($cur->post_format == 'wiki') {
488               $cur->post_content = $this->cleanStr($rs->post_content_wiki);
489               $cur->post_excerpt = $this->cleanStr($rs->post_chapo_wiki);
490          } else {
491               $cur->post_content = $this->cleanStr($rs->post_content);
492               $cur->post_excerpt = $this->cleanStr($rs->post_chapo);
493          }
494         
495          $cur->post_notes        = $this->cleanStr($rs->post_notes);
496          $cur->post_status       = (integer) $rs->post_pub;
497          $cur->post_selected     = (integer) $rs->post_selected;
498          $cur->post_open_comment = (integer) $rs->post_open_comment;
499          $cur->post_open_tb      = (integer) $rs->post_open_tb;
500          $cur->post_lang         = $rs->post_lang;
501         
502          $cur->post_words = implode(' ',text::splitWords(
503               $cur->post_title.' '.
504               $cur->post_excerpt_xhtml.' '.
505               $cur->post_content_xhtml
506          ));
507         
508          $cur->post_id = $this->con->select(
509               'SELECT MAX(post_id) FROM '.$this->prefix.'post'
510               )->f(0) + 1;
511         
512          $cur->insert();
513          $this->importComments($rs->post_id,$cur->post_id,$db);
514          $this->importPings($rs->post_id,$cur->post_id,$db);
515         
516          # Load meta if we have some in DC1
517          if (isset($this->has_table[$this->vars['db_prefix'].'post_meta'])) {
518               $this->importMeta($rs->post_id,$cur->post_id,$db);
519          }
520     }
521     
522     # Comments import
523     protected function importComments($post_id,$new_post_id,$db)
524     {
525          $count_c = $count_t = 0;
526         
527          $rs = $db->select(
528               'SELECT * FROM '.$this->vars['db_prefix'].'comment '.
529               'WHERE post_id = '.(integer) $post_id.' '
530               );
531         
532          while ($rs->fetch())
533          {
534               $cur = $this->con->openCursor($this->prefix.'comment');
535               $cur->post_id           = (integer) $new_post_id;
536               $cur->comment_author    = $this->cleanStr($rs->comment_auteur);
537               $cur->comment_status    = (integer) $rs->comment_pub;
538               $cur->comment_dt        = $rs->comment_dt;
539               $cur->comment_upddt     = $rs->comment_upddt;
540               $cur->comment_email     = $this->cleanStr($rs->comment_email);
541               $cur->comment_content   = $this->cleanStr($rs->comment_content);
542               $cur->comment_ip        = $rs->comment_ip;
543               $cur->comment_trackback = (integer) $rs->comment_trackback;
544               
545               $cur->comment_site = $this->cleanStr($rs->comment_site);
546               if ($cur->comment_site != '' && !preg_match('!^http://.*$!',$cur->comment_site)) {
547                    $cur->comment_site = substr('http://'.$cur->comment_site,0,255);
548               }
549               
550               if ($rs->exists('spam') && $rs->spam && $rs->comment_status = 0) {
551                    $cur->comment_status = -2;
552               }
553               
554               $cur->comment_words = implode(' ',text::splitWords($cur->comment_content));
555               
556               $cur->comment_id = $this->con->select(
557                    'SELECT MAX(comment_id) FROM '.$this->prefix.'comment'
558               )->f(0) + 1;
559               
560               $cur->insert();
561               
562               if ($cur->comment_trackback && $cur->comment_status == 1) {
563                    $count_t++;
564               } elseif ($cur->comment_status == 1) {
565                    $count_c++;
566               }
567          }
568         
569          if ($count_t > 0 || $count_c > 0)
570          {
571               $this->con->execute(
572                    'UPDATE '.$this->prefix.'post SET '.
573                    'nb_comment = '.$count_c.', '.
574                    'nb_trackback = '.$count_t.' '.
575                    'WHERE post_id = '.(integer) $new_post_id.' '
576               );
577          }
578     }
579     
580     # Pings import
581     protected function importPings($post_id,$new_post_id,$db)
582     {
583          $urls = array();
584         
585          $rs = $db->select(
586               'SELECT * FROM '.$this->vars['db_prefix'].'ping '.
587               'WHERE post_id = '.(integer) $post_id
588               );
589         
590          while ($rs->fetch())
591          {
592               $url = $this->cleanStr($rs->ping_url);
593               if (isset($urls[$url])) {
594                    continue;
595               }
596               
597               $cur = $this->con->openCursor($this->prefix.'ping');
598               $cur->post_id = (integer) $new_post_id;
599               $cur->ping_url = $url;
600               $cur->ping_dt = $rs->ping_dt;
601               $cur->insert();
602               
603               $urls[$url] = true;
604          }
605     }
606     
607     # Meta import
608     protected function importMeta($post_id,$new_post_id,$db)
609     {
610          $rs = $db->select(
611               'SELECT * FROM '.$this->vars['db_prefix'].'post_meta '.
612               'WHERE post_id = '.(integer) $post_id.' '
613               );
614         
615          if ($rs->isEmpty()) {
616               return;
617          }
618         
619          while ($rs->fetch()) {
620               $this->core->meta->setPostMeta($new_post_id,$this->cleanStr($rs->meta_key),$this->cleanStr($rs->meta_value));
621          }
622     }
623}
624?>
Note: See TracBrowser for help on using the repository browser.

Sites map