Dotclear

source: plugins/importExport/inc/class.dc.import.dc1.php @ 270:48858be15bda

Revision 270:48858be15bda, 17.1 KB checked in by Franck <carnet.franck.paul@…>, 14 years ago (diff)

Changement d'année

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

Sites map