<?php
/*_____________________________________________________________________________
The flatimport importer is based on the Dotclear importer (itself from the Textpattern importer)
and the Dotclear 2 importexport plugin.
Import Dotclear 1.2.x or Dotclear 2.0-beta into WordPress 2.3
Initial version: november 2006 ; WP2.3 version: july 2007.
Forum: http://www.wordpress-fr.net/support/sujet-2944-import-dotclear-fichier-texte
_____________________________________________________________________________*/
if ( @ini_get('max_execution_time') == 50000 ) {
	@ini_set('max_execution_time', 38); # try to modify the max_execution_time for 1and1 50000 seconds
} elseif ( @ini_get('max_execution_time') < 1200 ) {
	@ini_set('max_execution_time', 1200); # try to modify the max_execution_time ; Free.fr 20 or 30 seconds
}
/** The Main Importer Class **/
class Flat_Import {

	function import_flat_file() {
		global $wpdb, $utw, $STagging, $STaggingAdmin, $fi_import_format, $fi_dc_tables, $fi_dc_cats, $fi_dcposts2wpposts, $fi_linkcat_pos, $fi_linkcat_link_id, $fi_link_pos, $fi_link_link_id, $fi_dcid2wpid, $post_old_strings, $post_new_strings, $wp_version, $fi_update_mode;

		$flatimport_version = '2.3.0.1'; # pour WP 2.3 13:53 01/08/2007
		$time_start = time();
		
		$table_recover_count = 20; # a point of control is taken after importing the following number of values for a given table
		$time_to_reload = 1; # number of seconds to substract from max_execution_time to have the timeout to reload the current page

		$max_execution_time = @ini_get('max_execution_time'); # usually 30 seconds, Free.fr 20 or 30 ; 1and1 50000
		/*_____________________________________________________________________________
		allow automatic recovery by setting the $max_execution_time variable
		uncomment the following line to force the timeout
		set the value to 38 for 1and1 server ; or other appropriate value
		_____________________________________________________________________________*/
		#$max_execution_time = 30;

		$automatic_recovery = false;
		if ( is_numeric($max_execution_time) ) { # validate if the server return a positive number
			if ($max_execution_time > 3) { # to control lower values: do not handle by automatic recovery a max_execution_time lower than this value
				$automatic_recovery = true;
			}
			if ($max_execution_time < 0) {
				$max_execution_time = NULL;
			}
		} else {
			$max_execution_time = NULL;
		}
		/*_____________________________________________________________________________
		comment/uncomment the following line to enable/disable the automatic recovery feature.
		The user must click on the displayed Continue button to proceed if disabled
		_____________________________________________________________________________*/
		#$automatic_recovery = false;
		
		$post_old_strings = array();
		$post_new_strings = array();
		if ( file_exists(dirname(__FILE__).'/../../wp-content/uploads/blog-backup-change.php') )
			include_once(dirname(__FILE__).'/../../wp-content/uploads/blog-backup-change.php');
		$fi_filename = dirname(__FILE__).'/../../wp-content/uploads/blog-backup.txt';
		$post_id_filename = dirname(__FILE__).'/../../wp-content/uploads/post_id_dc2wp.php';
		$fi_import_format = '';
		$fi_recover_filename = dirname(__FILE__).'/../../wp-content/uploads/blog-backup-recovery.txt';
		$fi_recover_mode = false;
		$recover_names = array(
			'fi_filename_size',
			'fi_file_pointer',
			'fi_dc_tables',
			'fi_dc_cats',
			'fi_dcposts2wpposts',
			'fi_table_cols',
			'fi_linkcat_pos',
			'fi_linkcat_link_id',
			'fi_link_pos',
			'fi_link_link_id',
			'fi_dcid2wpid',
			'fi_table_name',
			'fi_table_name_found',
			'fi_table_import',
			'fi_update_mode'
			);
		$dc_version = '';
		$replacement = array(
		'\n' => "\n",
		'\r' => "\r",
		'\"' => '"'
		);
		# Default link category
		$wp_def_link_category_name = __('Blogroll');
		$deflinkcat = is_term( $wp_def_link_category_name, 'link_category' );
		if ($deflinkcat) {
			$wp_def_link_category_id = $deflinkcat['term_id'];
		} else {
			$wp_def_link_category_id = Flat_Import::wp_create_link_category($wp_def_link_category_name);
		}
		
		if ( file_exists($fi_recover_filename) ) {
			if ( filesize($fi_recover_filename) > 0) {
				# test for a non empty point of control file (uses dynamic variables $$name and serialyse unserialyse), if yes proceed to recovery
				$fi_recover = @fopen($fi_recover_filename, "r");
				if ($fi_recover) {
					while (!feof($fi_recover)) {
						$serialized_line = fgets($fi_recover);
						$name_recover = trim(substr($serialized_line, 0, strpos($serialized_line, ' ')));
						$$name_recover = unserialize(trim(substr($serialized_line, strpos($serialized_line, ' '))));
					}
					fclose($fi_recover);
					/* dump recover vars
					foreach ($recover_names as $value) {
						echo '<pre>';
						print_r($$value);
						echo '</pre>';
						echo '<hr />';
					}
					# */
					$fi_recover_mode = true;
					# vérif des variables en recovery
					foreach ($recover_names as $value) {
						if ( !isset($$value) ) $fi_recover_mode = false;
					}
					if ( $fi_recover_mode ) {
						# check that the recovery data applies to the backup file
						if ( $fi_filename_size != filesize($fi_filename) ) $fi_recover_mode = false;
					}
					if ( $fi_recover_mode ) {
						$count = $fi_dc_tables[$fi_table_name] + $table_recover_count; # reinitialize count
					} else {
						$import_mode_str = ($fi_update_mode) ? ('<strong>'.__('Update').'</strong>') : ('<strong>'.__('Import').'</strong>');
						echo '<p><strong>'.__('Warning:').'</strong> '.__('Non valid blog-backup-recovery.txt').' ; '.__('switching to').' '.$import_mode_str.'</p>';
					}
				}
			}
		}
		if ( !$fi_recover_mode ) {
			$fi_dc_tables = array(
				'setting' => 0,
				'user' => 0,
				'categorie' => 0,
				'category' => 0,
				'link' => 0,
				'post' => 0,
				'comment' => 0,
				'meta' => 0,
				'post_meta' => 0,
				'blog' => 0,
				'media' => 0,
				'version' => 0
				);
			# categories dc ; nécessaires pour import des posts ; pour dc : id nom 
			$fi_dc_cats = array(); # id du cat dc => id de cat wp
			# association des commentaires aux billets (tableau de correspondance des IDs, table de translation des post_id dc en ID WP)
			$fi_dcposts2wpposts = array(); # table de translation des post_id dc en ID WP
			# association des liens à leur catégorie par position
			$fi_linkcat_pos = array(); # on associe au cat_id ds wp_linkcategories la position dc
			$fi_linkcat_link_id = array(); # on associe au cat_id ds wp_linkcategories le link_id dc
			$fi_link_pos = array(); # on associe au link_id ds wp_links la position dc
			$fi_link_link_id = array(); # on associe au cat_id ds wp_linkcategories le link_id dc
			$fi_dcid2wpid = array(); # key: dc user_id (admin) => value: wp ID (1)
			$fi_table_name = '';
			$fi_table_name_found = array();
			$fi_table_import = false;
		}
		
		$backup = @fopen($fi_filename, "r");
		if ($backup)
		{
			$first_line = fgets($backup);
			
			if (strpos($first_line,'///DOTCLEAR|') === false) { # accepte fichier UTF8 avec ou sans BOM
				echo __('File is not a DotClear backup.');
				return;
			}
			
			$l = explode('|',$first_line);
			
			if (isset($l[1])) {
				$dc_version = $l[1];
			}
			/*
			$mode = isset($l[2]) ? strtolower(trim($l[2])) : 'single';
			if ($mode != 'full' && $mode != 'single') {
				$mode = 'single';
			}
			# */
			$fi_import_format = substr($dc_version, 0 ,3);
			
			if ( ($fi_import_format == '1.2') OR ($fi_import_format == '2.0') ) {
				$import_mode_str = ($fi_update_mode) ? ('<strong>'.__('Update').'</strong>') : ('<strong>'.__('Import').'</strong>');
				$auto_str = $automatic_recovery ? (__('Automatic recovery')) : ('<strong>'.__('No automatic recovery').'</strong>');
				$timeout_str = is_null($max_execution_time) ? '' : (__('Timeout').': '.$max_execution_time.' '.__('seconds'));
				Flat_Import::say('Version: '.$flatimport_version.' - '.$import_mode_str.' '.__('from Dotclear version').' <strong>'.$dc_version.
				'</strong> to WordPress <strong>'.get_bloginfo('version').
				'</strong> - '.__('data base formats').': dc '.$fi_import_format.' - '.
				$auto_str.' - '.$timeout_str.'<br />');
			} else {
				echo __('Unknown version of Dotclear for import file.').' - '.$first_line.' - '.$dc_version.' - '.$fi_import_format.'<br />';
				return;
			}
			/*_____________________________________________________________________________
			Recovery mode
			_____________________________________________________________________________*/
			if ($fi_recover_mode) { # the script was interrupted by the server ; retry from the last point of control taken
				fseek($backup, $fi_file_pointer);
				Flat_Import::say('<strong>'.__('Entering recovery mode').'</strong> '.__('from the pointer position:').
				' <strong>'.number_format($fi_file_pointer, 0, ',', ' ').'</strong> - '.
				Flat_Import::filesize_format($fi_file_pointer).'<br />');
			}
			/*_____________________________________________________________________________
			Read each entry in blog-backup and proceed
			_____________________________________________________________________________*/
			while (!feof($backup))
			{
				$line = trim(fgets($backup));
				
				if (substr($line,0,1) == '[') { # importation d'une table : le nom de la table est suivi des noms de champs
					if ( $fi_table_import AND ($fi_table_name != '') AND ($fi_dc_tables[$fi_table_name] > 0) ) {
					# affichage de fin d'import d'une table et du nombre d'éléments traités
						Flat_Import::say('<strong>'.__('Import of').' '.$fi_table_name.' : '.$fi_dc_tables[$fi_table_name].'</strong>');
					}
					
					$count = $table_recover_count; # new table : init count to do a point of control and and display an user message every 20 values for a table
					
					$fi_table_name = substr($line,1,strpos($line,' ')-1);
					Flat_Import::say('<em>'.__('Working with table:').' '.$fi_table_name.'</em>');
					$line = substr($line,strpos($line,' ')+1,-1);
					$fi_table_cols = explode(',',$line);
					$fi_table_import = true;
					if (array_key_exists($fi_table_name, $fi_dc_tables)) {
						$fi_table_name_found[] = $fi_table_name;
						# conditions d'import et de précédence des tables
						if ( ($fi_table_name == 'post_meta') OR ($fi_table_name == 'meta') ) {
							if ( in_array('post', $fi_table_name_found) ) {
								Flat_Import::say('<em>'.__('Importing tags').'</em>');
							} else {
								$fi_table_import = false;
								Flat_Import::say('<strong>'.__('Error:').'</strong> '.__('No import of tags. No posts found.'));
							}
						}
						if ($fi_table_name == 'comment') {
							if ( !in_array('post', $fi_table_name_found) ) {
								$fi_table_import = false;
								Flat_Import::say('<strong>'.__('Error:').'</strong> '.__('No import of comments. No posts found.'));
							}
						}
						if ($fi_table_name == 'post') {
							$post_import_msg = true;
							if (!( ( in_array('categorie', $fi_table_name_found) ) OR ( in_array('category', $fi_table_name_found) ) )) {
								$post_import_msg = false;
								Flat_Import::say('<strong>'.__('Warning:').'</strong> '.__('No categories found. All posts associated to the ID 1 category'));
							}
							if ( !( in_array('user', $fi_table_name_found) ) ) {
								Flat_Import::say('<strong>'.__('Warning:').'</strong> '.__('No users found. All posts associated to admin'));
							}
						}
					} else {
						echo __('No import for table').' <strong>'.$fi_table_name.'</strong><br />';
						$fi_table_import = false;
					}
				} elseif (substr($line,0,1) == '"') { # importation des valeurs d'une table
					if ($fi_table_import) {
						if (array_key_exists($fi_table_name, $fi_dc_tables)) {
							$line1 = preg_replace('/^"|"$/','',$line);
							$line_split = preg_split('/(^"|","|"$)/m',$line1);
							
							if (count($fi_table_cols) != count($line_split)) {
								echo __('Import of').' '.$fi_table_name.': invalid row count'.' - '.htmlspecialchars($line).'<br />';
							} else {
								#Flat_Import::say(substr($line,0,100).'&hellip;'.'|'.$fi_dc_tables[$fi_table_name].'|'.$count.'|'.'<br />');
							}
							$res = array();
							for ($i=0; $i<count($line_split); $i++) {
								$res[$fi_table_cols[$i]] =
								str_replace(array_keys($replacement),array_values($replacement),$line_split[$i]);
							}
							call_user_func(array('Flat_Import', $fi_table_name), $res); # appel des fonctions d'import, import des valeurs d'une entrée de table
							
							# message and point of control every 20 table values ( value of $table_recover_count) or timeout reached
							if ( is_null($max_execution_time) ) {
								$exec_time_left = 1; # set it for a positive value so we will never reload the current page
								$exec_time_left_str = '';
							} else {
								$exec_time_now = time()- $time_start;
								$exec_time_left = ($max_execution_time - $time_to_reload) - $exec_time_now;
								$exec_time_left_str = '+'.$exec_time_now.' - '.$exec_time_left.' '.__('seconds left');
							}
							if ( ($fi_dc_tables[$fi_table_name] == $count) OR ($exec_time_left <= 0) ) {
								$count = $count + $table_recover_count;
								
								Flat_Import::say(__('Import of').' '.$fi_table_name.' : '.$fi_dc_tables[$fi_table_name].'&hellip;'.$exec_time_left_str);
								
								# take a point of control ; for blog-backup.txt : size to check the right file, pointeur position, then needed variables
								# serialize() arrays, vars and save them to be able to recover an interrupted import ; uses dynamic variables
								
								# delete the backup of the recovery file ; then backup it ; to allow manual recovery if the following code is interrupted
								if ( file_exists($fi_recover_filename.'.bak') ) unlink($fi_recover_filename.'.bak');
								if ( file_exists($fi_recover_filename) ) rename($fi_recover_filename, $fi_recover_filename.'.bak');
								
								$fi_filename_size = filesize($fi_filename); # to check file at recovery time
								$fi_file_pointer = ftell($backup); # take the current pointer position
								$fi_recover = fopen($fi_recover_filename, 'wb'); # open and create or empty the recovery file
								foreach ($recover_names as $value) {
									fwrite($fi_recover, $value.' '.serialize($$value)."\r\n"); # output serialysed vars
								}
								fclose($fi_recover);
								
								# reload the current page if timeout reached either by meta refresh or by clic on the Continue button
								# cannot use register_shutdown_function(): one cannot send any HTTP header in the shutdown callback
								# When zlib compression is enabled, register_shutdown_function doesn't work properly.
								# Anything output from your shutdown function will not be readable by the browser. Firefox just ignores it. IE6 will show you a blank page.
								if ($exec_time_left <= 0) {
									$recover_step = ($fi_update_mode) ? 2 : 1; # Update : Import
									$import_mode_str = ($fi_update_mode) ? ('<strong>'.__('Update').'</strong>') : ('<strong>'.__('Import').'</strong>');
									echo '<form action="admin.php?import=flatimport&amp;step='.$recover_step.'" method="post">';
									wp_nonce_field('import-flatimport');
									echo '<input type="submit" name="submit" value="'.attribute_escape(__('Continue')).'" />';
									echo ' '.__('Click on the <strong>Continue</strong> button to continue the').
									' '.$import_mode_str.' '.__('<em>(by reloading the page to reset the timeout)</em>').'.';
									echo '</form>';
									
									if ($automatic_recovery) {
										/*
										We want to avoid any  message like: Warning: the page you are refreshing contains POST data... with a mandatory click needed.
										This is the case here for PHP header(Location: ... and JavaScript location.reload() ; some remaining blanks characters or others not found.
										
										META refresh is deprecated by W3C ; should not be used for redirecting to a new address (this is not the case here).
										Reloading the current page using meta refresh works for Firefox 2 and IE7.
										
										Do the meta refresh, it won't resend the data, 0 is the time in seconds, reload the current page as the url is omitted.
										The user will use the Continue button if the meta refresh is not granted by the navigator or the server.
										*/
										echo Flat_Import::wp_nonce_meta_refresh('import-flatimport', 'admin.php?import=flatimport&step=3'); # do the meta refresh
									}
									# terminate
									fclose($backup);
									ob_flush();flush(); # send all
									exit; # end the execution of this script
								}
							}
						}
					}
				} else {
					if ($line != '') {
						if (strlen($line) > 100) $line = substr($line,0,100).'&hellip;';
						echo __('Unknown line').' <i>'.htmlspecialchars($line).'</i><br />';
					}
				}
			}
			fclose($backup);
			if ( ($fi_table_name != '') AND ($fi_dc_tables[$fi_table_name] > 0) )
				echo '<strong>'.__('Import of').' '.$fi_table_name.' : '.$fi_dc_tables[$fi_table_name].'</strong><br />';
			/*_____________________________________________________________________________
			Associate links to link categories
			must be done here in post-processing due to the positional structure of the dc link table
			_____________________________________________________________________________*/
			if ( (count($fi_linkcat_pos)>0) AND (count($fi_link_pos)>0) ) {
				# associate links to cat based on dc position OR link_id if all dc positions at zero
				# $fi_linkcat_pos associe au cat_id ds wp_categories la position dc
				# $fi_linkcat_link_id associe au cat_id ds wp_categories le link_id dc
				# $fi_link_pos associe au link_id ds wp_links la position dc
				# $fi_link_link_id associe au link_id ds wp_links le link_id dc
				$link_pos_cumul = eval('return ' . implode('+', $fi_link_pos) . ';');
				if ($link_pos_cumul == 0) { # on prend le link_id si les positions sont à zéro
					$fi_linkcat_pos = $fi_linkcat_link_id;
					$fi_link_pos = $fi_link_link_id;
				}
				asort($fi_linkcat_pos); # tri les cat de liens par ordre croissant pour comparaison
				echo '<em>'.__('Associate links to link categories.').'</em>'.'<br />';
				foreach ($fi_link_pos as $_id => $_pos) { # pour chaque lien
					$link_cat = false;
					foreach ($fi_linkcat_pos as $_catid => $_catpos) {
						if ($_pos > $_catpos) {
							$link_cat = $_catid; # recherche d'une cat de lien en position avant celle du lien
						}
					}
					if ($link_cat === false) {
						$link_cat = $wp_def_link_category_id;
						echo __('Orphan link').' '.$_id.' - '.__('associated to default link category').' '.$wp_def_link_category_name.'<br />';
					}
					$ret_id = wp_set_link_cats($_id, array($link_cat));
				}
			}
			/*_____________________________________________________________________________
			Import post-processing
			_____________________________________________________________________________*/
			/*
			# on archive la table de translation des post_id dc en ID WP ;  $fi_dcposts2wpposts
			$post_id_dc2wp = fopen($post_id_filename, 'wb'); # open and create or empty the file
			fwrite($post_id_dc2wp, '<?php'."\r\n".'$post_old_strings = array('."\r\n");
			foreach ($fi_dcposts2wpposts as $key => $value) {
				fwrite($post_id_dc2wp, "'url_dc".$key."',"."\r\n");
			}
			fwrite($post_id_dc2wp, ');'."\r\n".'$post_new_strings = array('."\r\n");
			foreach ($fi_dcposts2wpposts as $key => $value) {
				fwrite($post_id_dc2wp, "'url_wp".$value."',"."\r\n");
			}
			fwrite($post_id_dc2wp, ');'."\r\n".'?>'."\r\n");
			fclose($post_id_dc2wp);
			#*/
			if ( file_exists($fi_recover_filename) ) unlink($fi_recover_filename);
			
			echo ' <strong>'.__('End of import').'.</strong>'.' '.
			__('Read carefully the following page').'. '.__('Hit the finish button').'<br />';
			echo '<form action="admin.php?import=flatimport&amp;step=4" method="post">';
			wp_nonce_field('import-flatimport');
			echo '<p><input type="submit" name="submit" value="'.attribute_escape(__('Finish')).'" /></p>';
			echo '</form>';
			# End of import post-processing
		} else {
			echo '<p><strong>'.__('Warning:').'</strong> '.__('No import file found').
			' <em>wp-content/uploads/blog-backup.txt</em></p>'.'<p>'.__('Unable to open:').' '.$fi_filename.'</p>';
		}
	}
	/*_____________________________________________________________________________
		Processing of table entries
	_____________________________________________________________________________*/
	function blog($blog) {
		global $wpdb, $fi_import_format, $fi_dc_tables;
		# nop
	}
	
	function setting($setting) {
		global $wpdb, $fi_import_format, $fi_dc_tables;
		# nop
	}
	
	function media($media) {
		global $wpdb, $fi_import_format, $fi_dc_tables;
		# nop
	}
	
	function version($version) {
		global $wpdb, $fi_import_format, $fi_dc_tables;
		# nop
	}

	function category($category) {
		Flat_Import::categorie($category, 'category');
	}
	function categorie($category, $fi_table_name='categorie') {
		global $wpdb, $fi_dc_cats, $fi_import_format, $fi_dc_tables, $fi_update_mode;
		
		extract($category);
		// Make Nice Variables
		if ($fi_import_format == '2.0') {
			$cat_libelle = $cat_title;
			$cat_libelle_url = $cat_url;
		}
		$name = $wpdb->escape($cat_libelle_url);
		$title = $wpdb->escape($cat_libelle);
		$desc = $wpdb->escape($cat_desc);
		
		if($cinfo = category_exists($name)) {
			if ($fi_update_mode) {
				$wp_cat_id = wp_update_category(array(
					'cat_ID' => $cinfo,
					'category_nicename' => $name,
					'cat_name' => addslashes($title),
					'category_description' => $desc
					));
				$fi_dc_tables[$fi_table_name]++;
			} else {
				$wp_cat_id = $cinfo;
			}
		} else {
			$wp_cat_id = wp_insert_category(array(
				'category_nicename' => $name,
				'cat_name' => addslashes($title),
				'category_description' => $desc
				));
			$fi_dc_tables[$fi_table_name]++;
		}
		$fi_dc_cats[$cat_id] = $wp_cat_id; # nécessaire pour assoc de post à post_cat ; array( dc cat iod => wp cat id )
	}

	function user($user) {
		global $wpdb, $fi_import_format, $fi_dc_tables, $fi_dcid2wpid, $fi_update_mode;
		extract($user);
		if ($user_id == 'admin') {
			$fi_dcid2wpid[$user_id] = 1; # set dc user_id admin to wp user ID 1
			return; # don't modify WordPress admin
		}
		if ($fi_import_format == '2.0') {
			$user_nom = $user_name;
			$user_prenom = $user_firstname;
			$user_pseudo = $user_displayname;
		}

		$user_login = $wpdb->escape($user_id); # was $name
		if($user_pseudo != '') { # Dotclear 1.2 : on affiche le pseudo s'il existe, sinon prénom nom
		  $display_name = $wpdb->escape($user_pseudo);
		} else {
			if($user_prenom != '') {
				$display_name = $wpdb->escape(trim($user_prenom.' '.$user_nom));
			} else {
				$display_name = $wpdb->escape(trim($user_nom));
			}
		}
		if($uinfo = get_userdatabylogin($user_login)) {
			if ($fi_update_mode) {
				$ret_id = wp_update_user(array(
					'ID'		=> $uinfo->ID,
					'user_login'	=> $user_login,
					'user_nicename'	=> $display_name,
					'user_email'	=> $user_email,
					'user_url'	=> 'http://',
					'display_name'	=> $display_name
					));
				$fi_dc_tables['user']++;
			} else {
				$ret_id = $uinfo->ID;
				$update_meta = false;
			}
		} else {
			$ret_id = wp_insert_user(array(
				'user_login'	=> $user_login,
				'user_nicename'	=> $user_pseudo,
				'user_email'	=> $user_email,
				'user_url'	=> 'http://',
				'display_name'	=> $display_name
				));
			$fi_dc_tables['user']++;
			$update_meta = true;
		}
		$fi_dcid2wpid[$user_id] = $ret_id;
		
		if ($update_meta) {
			// Set Dotclear-to-WordPress permissions translation
			// Update Usermeta Data
			$user = new WP_User($ret_id);
			$wp_perms = $user_level + 1;
			if(10 == $wp_perms) { $user->set_role('administrator'); }
			else if(9  == $wp_perms) { $user->set_role('editor'); }
			else if(5  <= $wp_perms) { $user->set_role('editor'); }
			else if(4  <= $wp_perms) { $user->set_role('author'); }
			else if(3  <= $wp_perms) { $user->set_role('contributor'); }
			else if(2  <= $wp_perms) { $user->set_role('contributor'); }
			else                     { $user->set_role('subscriber'); }
			
			update_usermeta( $ret_id, 'wp_user_level', $wp_perms);
			update_usermeta( $ret_id, 'rich_editing', 'false');
			update_usermeta( $ret_id, 'first_name', $user_prenom);
			update_usermeta( $ret_id, 'last_name', $user_nom);
			update_usermeta( $ret_id, 'nickname', $user_pseudo);
		}
	}// End function user

	function post($post) {
		global $wpdb, $fi_dc_cats, $fi_dcposts2wpposts, $fi_import_format, $fi_dc_tables, $fi_dcid2wpid, $post_old_strings, $post_new_strings, $post_import_msg, $fi_update_mode;
		extract($post);
		if ($fi_import_format == '2.0') {
			$post_titre = $post_title;
			$post_content = $post_content_xhtml;
			$post_chapo = $post_excerpt_xhtml;
			$post_pub = $post_status;
		}
		if ( isset($post_type) ) {
			if($post_type != 'post') {
				$post_type = ($post_type == 'related') ? $post_type = 'page' : $post_type = 'post';
				}
		} else {
			$post_type = 'post';
		}
		# associate post to wp user ; if dc user not found default to user ID 1 admin
		if ( array_key_exists($user_id, $fi_dcid2wpid) ) {
			$post_author = $fi_dcid2wpid[$user_id];
		} else {
			$post_author = 1;
		}
		# replace strings, example: old URL by new URL
		$post_content = str_replace($post_old_strings, $post_new_strings, $post_content);

		// Set Dotclear-to-WordPress status translation
		$stattrans = array(0 => 'draft', 1 => 'publish');
		$comment_status_map = array (0 => 'closed', 1 => 'open');
		
		$Title = $wpdb->escape($post_titre);
		$post_content = preg_replace ('|(?<!<br />)\s*\n|', ' ', $post_content);
		$post_excerpt = ""; # http://trac.wordpress.org/ticket/2430
		if ($post_chapo != "") {
			$post_excerpt = preg_replace ('|(?<!<br />)\s*\n|', ' ', $post_chapo);
			$post_content = $post_excerpt ."\n<!--more-->\n".$post_content;
		}
		$post_excerpt = $wpdb->escape ($post_excerpt);
		$post_content = $wpdb->escape ($post_content);
		$post_status = $stattrans[$post_pub];
		
		// Import Post data into WordPress
		
		if($pinfo = post_exists($Title,$post_content)) {
			if ($fi_update_mode) {
				$wp_post_id = wp_update_post(array(
					'ID'				=> $pinfo,
					'post_author'		=> $post_author,
					'post_date'			=> $post_dt,
					'post_date_gmt'		=> $post_dt,
					'post_modified'		=> $post_upddt,
					'post_modified_gmt'	=> $post_upddt,
					'post_title'		=> $Title,
					'post_content'		=> $post_content,
					'post_excerpt'		=> $post_excerpt,
					'post_status'		=> $post_status,
					'post_name'			=> $post_titre_url,
					'comment_status'	=> $comment_status_map[$post_open_comment],
					'ping_status'		=> $comment_status_map[$post_open_tb],
					'post_type'			=> $post_type,
					'comment_count'		=> $post_nb_comment + $post_nb_trackback)
					);
				$fi_dc_tables['post']++;
			} else {
				$wp_post_id = $pinfo;
			}
		} else {
			$wp_post_id = wp_insert_post(array(
				'post_author'		=> $post_author,
				'post_date'			=> $post_dt,
				'post_date_gmt'		=> $post_dt,
				'post_modified'		=> $post_modified_gmt,
				'post_modified_gmt'	=> $post_modified_gmt,
				'post_title'		=> $Title,
				'post_content'		=> $post_content,
				'post_excerpt'		=> $post_excerpt,
				'post_status'		=> $post_status,
				'post_name'			=> $post_titre_url,
				'comment_status'	=> $comment_status_map[$post_open_comment],
				'ping_status'		=> $comment_status_map[$post_open_tb],
				'post_type'			=> $post_type,
				'comment_count'		=> $post_nb_comment + $post_nb_trackback)
				);
			$fi_dc_tables['post']++;
		}
		$fi_dcposts2wpposts[$post_id] = $wp_post_id; # table de translation des post_id dc en ID WP
		
		/*_____________________________________________________________________________
		Make Post-to-Category associations
		assoc de post à post_cat ; array( dc cat id => wp cat id )
		_____________________________________________________________________________*/
		if ( array_key_exists($cat_id, $fi_dc_cats) ) { 
			$wp_cat_id = $fi_dc_cats[$cat_id];
			# Flat_Import::say($post_id.' '.$wp_post_id.' '.$wp_cat_id.' '.get_cat_name($wp_cat_id)); # 1 3 7 Tester le bouzin
			$cinfo = wp_set_post_categories($wp_post_id, array($wp_cat_id));
		} else {
			if ($post_import_msg) {
				echo __('No category for post').' '.$post_id.' - '.__('associated to first category ID 1').'<br />';
			}
			$cats = get_category_to_edit(1);
			wp_set_post_categories($wp_post_id, $cats);
		}
		
	}
	
	function comment($comment) {
		global $wpdb, $fi_dcposts2wpposts, $fi_import_format, $fi_dc_tables, $fi_update_mode;
		
		extract($comment);
		if ($fi_import_format == '2.0') {
			$comment_auteur = $comment_author;
			$comment_pub = $comment_status;
		}
		// WordPressify Data
		$comment_ID = ltrim($comment_id, '0');
		if ( array_key_exists($post_id, $fi_dcposts2wpposts) ) { # orphans test
			$comment_post_ID = $fi_dcposts2wpposts[$post_id];
		} else {
			$comment_post_ID = 1; # pas de billet associé, associe à billet ID 1
			echo __('Orphan comment').' '.__('associated to first post ID 1').'<br />';
		}
		$comment_approved = "$comment_pub";
		$name = $wpdb->escape($comment_auteur);
		$email = $wpdb->escape($comment_email);
		$web = "http://".$wpdb->escape($comment_site);
		$message = $wpdb->escape( preg_replace ('|(?<!<br />)\s*\n|', ' ', $comment_content) );
		if($cinfo = Flat_Import::wp_get_comment_ID($name, $comment_dt) ) {
			// Update comments
			if ($fi_update_mode) {
				$wp_comment_id = wp_update_comment(array(
					'comment_ID'		=> $cinfo,
					'comment_post_ID'	=> $comment_post_ID,
					'comment_author'	=> $name,
					'comment_author_email'	=> $email,
					'comment_author_url'	=> $web,
					'comment_author_IP'	=> $comment_ip,
					'comment_date'		=> $comment_dt,
					'comment_date_gmt'	=> $comment_dt,
					'comment_content'	=> $message,
					'comment_approved'	=> $comment_approved)
					);
				$fi_dc_tables['comment']++;
			} else {
				$wp_comment_id = $cinfo;
			}
		} else {
			// Insert comments
			$wp_comment_id = wp_insert_comment(array(
				'comment_post_ID'	=> $comment_post_ID,
				'comment_author'	=> $name,
				'comment_author_email'	=> $email,
				'comment_author_url'	=> $web,
				'comment_author_IP'	=> $comment_ip,
				'comment_date'		=> $comment_dt,
				'comment_date_gmt'	=> $comment_dt,
				'comment_content'	=> $message,
				'comment_approved'	=> $comment_approved)
				);
			$fi_dc_tables['comment']++;
		}
	} # comment
	
	function link($link) {
	/*
	la position détermine la catégorie de liens d'appartenance ; sauf si toutes les positions sont à zéro, c'est alors le link_id qui détermine la position
	ceci empêche l'assoc de lien à link_category ici ; on doit le faire en post-proc
	au départ on associe le lien à la catégorie cat_id 1 Blogroll pour les liens dc sans catégorie
	 associate links to cat based on dc position or link_id if all dc positions at zero
	 $fi_linkcat_pos associe au cat_id ds => wp_categories la position dc
	 $fi_linkcat_link_id associe au cat_id ds wp_categories => le link_id dc
	 $fi_link_pos associe au link_id ds wp_links => la position dc
	 $fi_link_link_id associe au link_id ds wp_links => le link_id dc
	*/
		global $wpdb, $fi_linkcat_pos, $fi_linkcat_link_id, $fi_link_pos, $fi_link_link_id, $fi_import_format, $fi_dc_tables, $fi_update_mode;
		extract($link);
		if ($fi_import_format == '2.0') {
			$href = $link_href;
			$label = $link_title;
			$title = $link_desc;
			$lang = $link_lang;
			$rel = $link_xfn;
			$position = $link_position;
		}
		$title = addslashes($title);
		if ( ($href == "") AND ($title != "") ) { # on traite une catégorie de lien
			if ( !($wp_link_category_id = Flat_Import::link_category_exists($title) ) ) {
				$wp_link_category_id = Flat_Import::wp_create_link_category($title);
			}
			$fi_linkcat_pos[$wp_link_category_id] = $position;
			$fi_linkcat_link_id[$wp_link_category_id] = $link_id;
		} else { # on traite un lien
			$linkname = $wpdb->escape($label);
			$description = $wpdb->escape($title);
			$wp_link_id = Flat_Import::link_exists($linkname, $href, $description);
			if($wp_link_id) {
				if ($fi_update_mode) {
					$ret_id = wp_update_link( array(
						'link_id'		=> $wp_link_id,
						'link_url'		=> $href,
						'link_name'		=> $linkname,
						'link_description'	=> $description
						)
						);
					$fi_dc_tables['link']++;
				} else {
					$ret_id = $wp_link_id;
				}
			} else {
				$ret_id = wp_insert_link( array(
					'link_url'		=> $href,
					'link_name'		=> $linkname,
					'link_description'	=> $description
					)
					);
				$fi_dc_tables['link']++;
			}
			$fi_link_pos[$ret_id] = $position;
			$fi_link_link_id[$ret_id] = $link_id;
		}
	}

	function post_meta($tags) {
		Flat_Import::meta($tags, 'post_meta');
	}
	function meta($tags, $fi_table_name='meta') 
	{
		global $wpdb, $utw, $STagging, $STaggingAdmin, $fi_import_format, $fi_dc_tables, $fi_dcposts2wpposts;
		extract($tags);
		$tag = '';
		if ($fi_import_format == '1.2') {
			if ($meta_key == 'tag') $tag = $meta_value;
		} elseif ($fi_import_format == '2.0') {
			if ($meta_type == 'tag') $tag = $meta_id;
		}
		if ($tag != '') {
			if ( array_key_exists($post_id, $fi_dcposts2wpposts) ) {
				$post_id = $fi_dcposts2wpposts[$post_id]; # get WP post_id
				wp_add_post_tags($post_id, $tag);
				$fi_dc_tables[$fi_table_name]++;
			}
		}
	}
	/*_____________________________________________________________________________
		some WP functions not found in WP 2.3
	_____________________________________________________________________________*/
	function wp_nonce_meta_refresh($action = -1, $url = 'admin.php', $name = "_wpnonce", $referer = true) {
		# do a meta refresh ; the original one was: echo '<meta http-equiv="refresh" content="0">'; to refresh the current page
		$name = attribute_escape($name);
		$ret = '<meta http-equiv="refresh" content="0;'.$url.'&'.$name.'='.wp_create_nonce($action).'">';
		if ( $referer )
			wp_referer_field();
		return $ret;
	}
	
	function wp_get_comment_ID($name, $comment_dt) {
		global $wpdb;
		return $wpdb->get_var("SELECT comment_ID FROM $wpdb->comments WHERE comment_author = '$name' AND comment_date = '$comment_dt'");
	}

	function link_exists($link_name, $link_url, $link_description) {
		global $wpdb;
		return $wpdb->get_var("SELECT link_id FROM $wpdb->links WHERE link_name = '$link_name' AND link_url = '$link_url' AND link_description = '$link_description'");
	}
	
	function link_category_exists($link_cat_name) {
		$id = is_term($link_cat_name, 'link_category');
		if ( is_array($id) )
			$id = $id['term_id'];
		return $id;
	}
	
	function wp_create_link_category($link_cat_name) {
	/*
	if ( $id = Flat_Import::link_category_exists($link_cat_name) )
		return $id;
	*/
	$id = wp_insert_term($link_cat_name, 'link_category');
	if ( is_array($id) )
		$id = $id['term_id'];
	return $id;
	}
	/*_____________________________________________________________________________
		miscellaneous functions
	_____________________________________________________________________________*/
	function filesize_format($bytes) {
		$bytes=(float)$bytes;
		if ($bytes<1024){
		$numero=number_format($bytes, 0, ',', '.')." Byte";
		return $numero;
		}
		if ($bytes<1048576){
		 $numero=number_format($bytes/1024, 2, ',', '.')." KByte";
		return $numero;
		}
		if ($bytes>=1048576){
		 $numero=number_format($bytes/1048576, 2, ',', '.')." MByte";
		return $numero;
		}
	}

	function say($str) { # add html tags and force output
		echo $str.'<br />';
		ob_flush();flush();
	}
	/*_____________________________________________________________________________
		Admin display
	_____________________________________________________________________________*/
	function tips() {
		echo '<p>'.__('Welcome to WordPress.  We hope (and expect!) that you will find this platform incredibly rewarding!  As a new WordPress user coming from Dotclear, there are some things that we would like to point out.  Hopefully, they will help your transition go as smoothly as possible.').'</p>';
		echo '<h3>'.__('Users').'</h3>';
		echo '<p>'.sprintf(__('You have already setup WordPress and have been assigned an administrative login and password.  This one (admin) is preserved.  We have taken care to import all of your users into our system (except the admin one).  It is safe to change your passwords.  So <a href="%1$s">Login</a> and change them.'), '../wp-login.php').'</p>';
		echo '<h3>'.__('Preserving Authors').'</h3>';
		echo '<p>'.__('We have attempted to preserve post authors.  If you are the only author or contributor to your blog, then you are safe.  In most cases, we are successful in this preservation endeavor.  However, if we cannot ascertain the name of the writer due to discrepancies between database tables, we assign it to you, the administrative user.').'</p>';
		echo '<h3>'.__('WordPress Resources').'</h3>';
		echo '<p>'.__('Finally, there are numerous WordPress resources around the internet.  Some of them are:').'</p>';
		echo '<ul>';
		echo '<li>'.__('<a href="http://www.wordpress.org">The official WordPress site</a>').'</li>';
		echo '<li>'.__('<a href="http://wordpress.org/support/">The WordPress support forums</a>').'</li>';
		echo '<li>'.__('<a href="http://codex.wordpress.org">The Codex (In other words, the WordPress Bible)</a>').'</li>';
		echo '</ul>';
		echo '<p>'.sprintf(__('That\'s it! What are you waiting for? Go <a href="%1$s">login</a>!'), '../wp-login.php').'</p>';
	}

	function header() {
		echo '<div class="wrap">';
		echo '<h2>'.__('Import Dotclear').'</h2>';
	}

	function footer() {
		echo '</div>';
	}
	
	function greet() {
		$filename = dirname(__FILE__).'/../../wp-content/uploads/blog-backup.txt';
		$filename_exists = ( file_exists($filename) ) ? true : false;
		$recover_filename = dirname(__FILE__).'/../../wp-content/uploads/blog-backup-recovery.txt';
		$recover_exists = ( file_exists($recover_filename) ) ? true : false;
		if ($recover_exists) {
			if ( filesize($recover_filename) == 0) $recover_exists = false;
		}
		echo '<p>'.__('This importer allows you to import a Dotclear blog into a WordPress blog.').'</p>';
		echo '<p>'.__('Import of posts (users, comments, categories, tags), links (categories), from DotClear 2 or Dotclear 1.2.x.').'</p>';
		echo '<p>'.__('It requires the <em>wp-contents/uploads/</em><strong>blog-backup.txt</strong> file.').'</p>';
		echo '<p>'.__('The first post <strong>ID 1</strong> ; <em>Hello World</em> initial name (for orphans comments) is required.').'</p>';
		echo '<p>'.__('If the importer do not display the message:').' <strong>'.__('End of import').'</strong>, '.
		__('then <strong>retry</strong> the import. Click <em>Import</em>, click <em>Dotclear flat import</em> and so on.').'</p>';
		echo '<p>'.__('<strong>Saving</strong> your existing WordPress data is <strong>mandatory</strong> before doing an import. The version 2 of <a href="http://www.ilfilosofo.com/blog/wp-db-backup">WordPress Database Backup</a> is recommended for WordPress 2.1+.').'</p>';
		if ( (WPLANG == 'fr_FR') AND ( file_exists('import/flatimport-tuto-fr.html')) ) {
			echo '<strong>Tutoriel:</strong> <a href="import/flatimport-tuto-fr.html">Comment importer un blog de Dotclear vers WordPress 2.3+</a>.';
		} elseif ( file_exists('import/flatimport-tuto.html') ) {
			echo '<strong>Tutorial:</strong> <a href="import/flatimport-tuto.html">How to import a blog from Dotclear to WordPress 2.3+</a>';
		}
		echo '<p><strong>'.__('Forum:').'</strong> <a href="http://www.wordpress-fr.net/support/sujet-2944-import-dotclear-fichier-texte">[Import] Dotclear par fichier texte</a>.</p>';
		if ($filename_exists AND $recover_exists) {
			echo '<form action="admin.php?import=flatimport&amp;step=3" method="post">';
			wp_nonce_field('import-flatimport');
			echo '<input type="submit" name="submit" value="'.attribute_escape(__('Continue')).'" />';
			echo ' '.__('the import from the latest point of control (if not wanted, please delete the wp-contents/uploads/<strong>blog-backup-recovery.txt</strong> file ; then retry the import').'.';
			echo '</form>';
		} elseif ($filename_exists) {
			echo '<form action="admin.php?import=flatimport&amp;step=1" method="post">';
			wp_nonce_field('import-flatimport');
			echo '<input type="submit" name="submit" value="'.attribute_escape(__('Import')).'" />';
			echo ' '.__('Import posts (users, comments, tags, categories), links (categories). <em>New ones only</em>.');
			echo '</form>';
			echo '<form action="admin.php?import=flatimport&amp;step=2" method="post">';
			wp_nonce_field('import-flatimport');
			echo '<input type="submit" name="submit" value="'.attribute_escape(__('Update')).'" />';
			echo ' '.__('Update posts (users, comments, tags, categories), links (categories). <em>Import new ones, update already imported ones</em>.');
			echo '</form>';
		} else {
			echo '<p><strong>Warning:</strong> No wp-contents/uploads/<strong>blog-backup.txt</strong> file found.</p>';
		}
	}
	/*_____________________________________________________________________________
		main dispatching
	_____________________________________________________________________________*/
	function dispatch() {
		global $fi_update_mode;

		$step = ( empty($_GET['step']) ) ? 0 : ( (int) $_GET['step'] ); # securize numeric $_GET
		
		$this->header();

		if ( $step > 0 ) {
			check_admin_referer('import-flatimport');
		}
		
		switch ($step) {
			default:
			case 0 :
				$this->greet(); # Home
				break;
			case 1 :
				$fi_update_mode = false; # Import
				$this->import_flat_file();
				break;
			case 2 :
				$fi_update_mode = true; # Update
				$this->import_flat_file();
				break;
			case 3 :
				$fi_update_authorized = false; # Continue with the default for a non valid blog-backup-recovery.txt
				$this->import_flat_file();
				break;
			case 4 :
				$this->tips(); # Tips
				break;
		}
		$this->footer();
	}
	
	function Flat_Import() {
		// Nothing.	
	}
}
/*_____________________________________________________________________________
	define import object and execute
_____________________________________________________________________________*/
$fi_dc_import = new Flat_Import();
register_importer('flatimport', __('Dotclear flat import'), __('Import <strong>posts</strong><em>(users, comments, tags, categories)</em>, <strong>pages</strong><em>(as posts)</em>, <strong>links</strong><em>(categories)</em> from a Dotclear 2 or 1 export file'), array ($fi_dc_import, 'dispatch'));
?>
