<?php /*

 ocPortal
 Copyright (c) ocProducts, 2004-2012

 See text/EN/licence.txt for full licencing information.


 NOTE TO PROGRAMMERS:
   Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
   **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****

*/

/**
 * @license		http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
 * @copyright	ocProducts Ltd
 * @package 	import
 */

/**
 * Standard code module initialisation function.
 */
function init__hooks__modules__admin_import__smf()
{
	global $TOPIC_FORUM_CACHE;
	$TOPIC_FORUM_CACHE=array();

	global $STRICT_FILE;
	$STRICT_FILE=false; // Disable this for a quicker import that is quite liable to go wrong if you don't have the files in the right place
}

/**
 * Forum Driver.
 */
class Hook_smf
{

	/**
	 * Standard modular info function.
	 *
	 * @return ?array	Map of module info (NULL: module is disabled).
	 */
	function info()
	{
		$info=array();
		$info['supports_advanced_import']=false;
		$info['product']='SMF 1.1.x';
		$info['prefix']='smf_';
		$info['import']=array(
								'config',
								'ocf_groups',
								'ocf_members',
								'ocf_member_files',
								'ip_bans',
								'ocf_categories',
								'ocf_forums',
								'ocf_topics',
								'ocf_personal_topics',
								'ocf_posts',
								'ocf_post_files',
								'ocf_polls_and_votes',
								'notifications',
								'wordfilter',
								'calendar'
							);

		$info['dependencies']=array( // This dependency tree is overdefined, but I wanted to make it clear what depends on what, rather than having a simplified version
								'ocf_members'=>array('ocf_groups'),
								'ocf_member_files'=>array('ocf_members'),
								'ocf_forums'=>array('ocf_categories','ocf_members','ocf_groups'),
								'ocf_topics'=>array('ocf_forums','ocf_members'),
								'ocf_polls_and_votes'=>array('ocf_topics','ocf_members'),
								'ocf_posts'=>array('ocf_topics','ocf_members'),
								'ocf_post_files'=>array('ocf_posts','ocf_personal_topics'),
								'notifications'=>array('ocf_topics','ocf_members','ocf_polls_and_votes'),
								'ocf_personal_topics'=>array('ocf_members')
							);
		$_cleanup_url=build_url(array('page'=>'admin_cleanup'),get_module_zone('admin_cleanup'));
		$cleanup_url=$_cleanup_url->evaluate();
		$info['message']=(get_param('type','misc')!='import' && get_param('type','misc')!='hook')?new ocp_tempcode():do_lang_tempcode('FORUM_CACHE_CLEAR',escape_html($cleanup_url));

		return $info;
	}

	/**
	 * Probe a file path for DB access details.
	 *
	 * @param  string			The probe path
	 * @return array			A quartet of the details (db_name, db_user, db_pass, table_prefix)
	 */
	function probe_db_access($file_base)
	{
		$db_name='';
		$db_user='';
		$db_passwd='';
		$db_prefix='';
		$db_server='';
		if (!file_exists($file_base.'/Settings.php'))
			warn_exit(do_lang_tempcode('BAD_IMPORT_PATH',escape_html('Settings.php')));
		require($file_base.'/Settings.php');

		return array($db_name,$db_user,$db_passwd,$db_prefix,$db_server);
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_config($db,$table_prefix,$file_base)
	{
		$webmaster_email='';
		$mbname='';
		$boardurl='';
		$cookiename='';

		require($file_base.'/Settings.php');

		$rows=$db->query_select('settings');

		$config_remapping=array();
		$config_remapping['staff_address']=$webmaster_email;
		$config_remapping['site_name']=$mbname;
		$board_url=$boardurl;
		$config_remapping['site_name']=$mbname;
		$config_remapping['staff_address']=$webmaster_email;
		$additional_data=array();

		foreach ($rows as $row)
		{
			if (isset($row['variable'])&&$row['variable']=='topicSummaryPosts')
			{
				$config_remapping['forum_posts_per_page']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='newsletter_title')
			{
				$config_remapping['news']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='smtp_port')
			{
				$config_remapping['smtp_sockets_port']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='smtp_username')
			{
				$config_remapping['smtp_sockets_username']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='smtp_password')
			{
				$config_remapping['smtp_sockets_password']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='smtp_host')
			{
				$config_remapping['smtp_sockets_host']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='mail_type')
			{
				$config_remapping['smtp_sockets_use']=($row['value']=='1')?1:0;
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='databaseSession_lifetime')
			{
				$config_remapping['session_expiry_time']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='hotTopicPosts')
			{
				$config_remapping['hot_topic_definition']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='reserveNames')
			{
				$config_remapping['restricted_usernames']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='defaultMaxTopics')
			{
				$config_remapping['forum_topics_per_page']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='enableCompressedOutput')
			{
				$config_remapping['gzip_output']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='default_timezone')
			{
				$config_remapping['timezone']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='attachmentNumPerPostLimit')
			{
				$additional_data['maxattachments']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='avatar_max_width_upload')
			{
				$additional_data['avatar_max_width']=$row['value'];
				continue;
			}

			if (isset($row['variable'])&&$row['variable']=='avatar_max_height_upload')
			{
				$additional_data['avatar_max_height']=$row['value'];
				continue;
			}

		}

		$INFO=array();

		foreach ($config_remapping as $key=>$value)
		{
			if ($key!='timezone')
			{
				set_option($key,$value);
			} else
			{
				set_value('timezone',str_replace('Etc/GMT+','',$value));
			}

			$INFO[$key]=$row;
		}

		$groups=$GLOBALS['OCF_DRIVER']->get_usergroup_list();
		foreach ($groups as $id=>$groupname)
		{
			//if ($GLOBALS['OCF_DRIVER']->is_super_admin($id)) continue;
			if (preg_match('/Administrator/i',$groupname)!=0) continue;

			$GLOBALS['FORUM_DB']->query_update('f_groups',array('g_max_attachments_per_post'=>$additional_data['maxattachments'],'g_max_avatar_width'=>$additional_data['avatar_max_width'],'g_max_avatar_height'=>$additional_data['avatar_max_height']),array('id'=>$id),'',1);
		}

		$INFO['board_prefix']=$boardurl;
		$INFO['user_cookie']=$cookiename;
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ocf_groups($db,$table_prefix,$file_base)
	{
		require($file_base.'/Settings.php');

		$rows=$db->query('SELECT * FROM '.$table_prefix.'settings WHERE '.db_string_equal_to('variable','avatar_max_width_upload').' OR '.db_string_equal_to('variable','avatar_max_height_upload'));
		$INFO=array();
		foreach ($rows as $row)
		{
			$key=$row['variable'];
			$val=$row['value'];
			$INFO[$key]=$val;
		}

		$avatar_max_width=$INFO['avatar_max_width_upload'];
		$avatar_max_height=$INFO['avatar_max_height_upload'];

		$rows=$db->query('SELECT * FROM '.$table_prefix.'membergroups ORDER BY ID_GROUP');
		foreach ($rows as $row)
		{
			if (import_check_if_imported('group',strval($row['ID_GROUP']))) continue;

			$is_super_admin=($row['groupName']=='Administrator')?1:0;
			$is_super_moderator=($row['groupName']=='Global Moderator')?1:0;

			$id_new=$GLOBALS['FORUM_DB']->query_value_null_ok('f_groups g LEFT JOIN '.$GLOBALS['FORUM_DB']->get_table_prefix().'translate t ON g.g_name=t.id WHERE '.db_string_equal_to('text_original',$row['groupName']),'g.id');
			if (is_null($id_new))
			{
				$id_new=ocf_make_group($row['groupName'],0,$is_super_admin,$is_super_moderator,'','',NULL,NULL,NULL,5,0,5,5,$avatar_max_width,$avatar_max_height,30000);
			}

			// privileges
			set_specific_permission($id_new,'allow_html',true);

			if (!import_check_if_imported('group',strval($row['ID_GROUP'])))
				import_id_remap_put('group',strval($row['ID_GROUP']),$id_new);
		}
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ocf_members($db,$table_prefix,$file_base)
	{
		$row_start=0;
		$rows=array();

		$default_group=get_first_default_group();

		do
		{
			$rows=$db->query('SELECT u.ID_MEMBER AS \'muid\',u.*,b.* FROM '.$table_prefix.'members u LEFT JOIN '.$table_prefix.'ban_items b ON u.ID_MEMBER=b.ID_MEMBER WHERE u.ID_MEMBER<>-1 ORDER BY u.ID_MEMBER',200,$row_start);

			foreach ($rows as $row)
			{
				if (import_check_if_imported('member',strval($row['muid']))) continue;

				$test=$GLOBALS['OCF_DRIVER']->get_member_from_username($row['memberName']);
				if (!is_null($test))
				{
					import_id_remap_put('member',strval($row['muid']),$test);
					continue;
				}

				$language='EN';

				$secondary=explode(',',$row['additionalGroups']);
				$secondary_groups=array();
				foreach ($secondary as $g)
				{
					if (trim($g)!='')
					{
						$g=import_id_remap_get('group',$g,true);
						if (!is_null($g)) $secondary_groups[]=intval($g);
					}
				}

				$primary_group=$row['ID_GROUP'];
				if ($primary_group==0) $primary_group=$row['ID_POST_GROUP'];
				if ($primary_group==0)
				{
					$primary_group=$default_group;
				} else
				{
					$primary_group=import_id_remap_get('group',strval($primary_group));
				}

				$custom_fields=array(
										ocf_make_boiler_custom_field('im_icq')=>$row['ICQ'],
										ocf_make_boiler_custom_field('im_aim')=>$row['AIM'],
										ocf_make_boiler_custom_field('im_msn')=>$row['MSN'],
										ocf_make_boiler_custom_field('im_yahoo')=>$row['YIM'],
									);
				if ($row['websiteUrl']!='')
					$custom_fields[ocf_make_boiler_custom_field('website')]=$row['websiteUrl'];

				$signature=$this->fix_links($row['signature'],$db,$table_prefix,$file_base);
				$validated=1;
				$reveal_age=0;

				if ($row['birthdate']!='')
				{
					$birthdate=$row['birthdate'];
					$birthdata=explode('-',$birthdate);
					$bday_day=(isset($birthdata[0])&&($birthdata[0]!=''))?$birthdata[0]:NULL;
					$bday_month=(isset($birthdata[1])&&($birthdata[1]!=''))?$birthdata[1]:NULL;
					$bday_year=(isset($birthdata[2])&&($birthdata[2]!=''))?$birthdata[2]:NULL;
				}
				else
					list($bday_day,$bday_month,$bday_year)=array(NULL,NULL,NULL);

				$views_signatures=1;
				$preview_posts=1;
				$track_posts=$row['notifyAnnouncements'];
				$title='';

				// These are done in the members-files stage
				$avatar_url='';
				$photo_url='';
				$photo_thumb_url='';

				$password=$row['passwd'];
				$type='smf';
				$salt=$row['passwordSalt'];

				if ($row['dateRegistered']==0) $row['dateRegistered']=time();
				$id_new=ocf_make_member($row['memberName'],$password,$row['emailAddress'],NULL,$bday_day,$bday_month,$bday_year,$custom_fields,strval($row['timeOffset']),$primary_group,$validated,$row['dateRegistered'],$row['lastLogin'],'',$avatar_url,$signature,0,$preview_posts,$reveal_age,$title,$photo_url,$photo_thumb_url,$views_signatures,$track_posts,$language,$row['instantMessages'],1,'','','',false,$type,$salt,1);

				// Fix usergroup leadership
				$GLOBALS['FORUM_DB']->query_update('f_groups',array('g_group_leader'=>$id_new),array('g_group_leader'=>-$row['muid']));

				import_id_remap_put('member',strval($row['muid']),$id_new);

				// Set up usergroup membership
				foreach ($secondary_groups as $s)
				{
					ocf_add_member_to_group($id_new,$s,1);
				}
			}

			$row_start+=200;
		}
		while (count($rows)>0);
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ocf_member_files($db,$table_prefix,$file_base)
	{
		$boardurl='';
		$boarddir='';

		global $STRICT_FILE;
		require($file_base.'/Settings.php');

		$options=$db->query('SELECT * FROM '.$table_prefix.'settings WHERE variable LIKE \''.db_encode_like('%avatar%').'\'');
		$options_array=array();

		$homeurl=$boardurl;

		$avatar_path='';
		$avatar_gallery_path='';
		$avatar_path='attachments';

		foreach ($options as $option)
		{
			$options_array[$option['variable']]=$option['value'];

			if ($option['variable']=='avatar_url') $avatar_gallery_path=$option['value'];
		}

		$avatar_gallery_path=str_replace($boardurl, '', $avatar_gallery_path);

		$host=preg_replace('#\.#','\.',$_SERVER['HTTP_HOST']);
		$doc_root=$_SERVER['DOCUMENT_ROOT'];

		$forum_dir=preg_replace('#\\\\#','/',$boarddir);

		$avatar_gallery_path=$forum_dir.$avatar_gallery_path;
		$avatar_path=$forum_dir.'/'.$avatar_path;

		$row_start=0;
		$rows=array();
		do
		{
			$query='SELECT ID_MEMBER,avatar FROM '.$table_prefix.'members WHERE ID_MEMBER<>-1 ORDER BY ID_MEMBER';

			$rows=$db->query($query,200,$row_start);
			foreach ($rows as $row)
			{
				if (import_check_if_imported('member_files',strval($row['ID_MEMBER']))) continue;

				$member_id=import_id_remap_get('member',strval($row['ID_MEMBER']));

				$avatar_url='';
				if (!isset($row['avatar'])||(strlen($row['avatar'])==0))
				{
					$query_attachments='SELECT ID_MEMBER,filename,width,height,size,attachmentType FROM '.$table_prefix.'attachments WHERE attachmentType=\'0\' AND ID_MEMBER=\''.strval($row['ID_MEMBER']).'\'';

					$attachment_data=$db->query($query_attachments,1,0);
					if (isset($attachment_data[0]['filename'])&&(strlen($attachment_data[0]['filename'])>0))
					{
						// Uploaded avatar
						$filename=$attachment_data[0]['filename'];
						if ((file_exists(get_custom_file_base().'/uploads/ocf_avatars/'.$filename)) || (@rename($avatar_path.'/'.$filename,get_custom_file_base().'/uploads/ocf_avatars/'.$filename)))
						{
							$avatar_url='uploads/ocf_avatars/'.$filename;
							sync_file($avatar_url);
						} else
						{
							if ($STRICT_FILE) warn_exit(do_lang_tempcode('MISSING_AVATAR',escape_html($filename)));
							$avatar_url='';
						}
					}
				} else
				{
					if (preg_match('#http\:#',$row['avatar'])!=0)
					{
						//Remote file is set as avatar
						$avatar_url=$row['avatar'];
					}
					elseif (strlen($row['avatar'])>0)
					{
						// Gallery
						$filename_with_subdir=$row['avatar'];
						$filename=preg_replace('#.*\/#','',$filename_with_subdir); //we need just a filename

						if ((file_exists(get_custom_file_base().'/uploads/ocf_avatars/'.$filename)) || (@rename($avatar_gallery_path.'/'.$filename_with_subdir,get_custom_file_base().'/uploads/ocf_avatars/'.$filename)))
						{
							$avatar_url='uploads/ocf_avatars/'.substr($filename,strrpos($filename,'/'));
							sync_file($avatar_url);
						} else
						{
							// Try as a pack avatar then
							$striped_filename=str_replace('/','_',$filename);
							if (file_exists(get_custom_file_base().'/uploads/ocf_avatars/'.$striped_filename))
							{
								$avatar_url='uploads/ocf_avatars/'.substr($filename,strrpos($filename,'/'));
							} else
							{
								if ($STRICT_FILE) warn_exit(do_lang_tempcode('MISSING_AVATAR',escape_html($filename)));
								$avatar_url='';
							}
						}
					}
				}

				$GLOBALS['FORUM_DB']->query_update('f_members',array('m_avatar_url'=>$avatar_url),array('id'=>$member_id),'',1);

				import_id_remap_put('member_files',strval($row['ID_MEMBER']),1);
			}

			$row_start+=200;
		}
		while (count($rows)>0);
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ip_bans($db,$table_prefix,$file_base)
	{
		global $SITE_INFO;

		require_code('failure');

		$rows=$db->query('SELECT * FROM '.$table_prefix.'ban_groups u LEFT JOIN '.$table_prefix.'ban_items b ON u.ID_BAN_GROUP=b.ID_BAN_GROUP');

		foreach ($rows as $row)
		{
			$ban_time=$row['ban_time']; //when is banned user
			$ban_till=$row['expire_time']; //member is banned until

			if (($ban_till>time()) || empty($ban_till))
			{
				$user=$db->query_select('members',array('ID_MEMBER'),array('memberName'=>$row['name']));

				if (isset($user[0]['ID_MEMBER'])&&($user[0]['ID_MEMBER']!=0))
				{
					$uid=$user[0]['ID_MEMBER'];

					if (empty($ban_till))
					{
						$GLOBALS['SITE_DB']->query_update('f_members',array('m_is_perm_banned'=>1),array('id'=>$uid));
					} else
					{
						$GLOBALS['SITE_DB']->query_update('f_members',array('m_on_probation_until'=>$ban_till),array('id'=>$uid));
					}

					if ($row['ip_low1']>=127 && empty($ban_till))
					{
						if (import_check_if_imported('ip_ban',strval($uid))) continue;

						for ($i=$row['ip_low1'];$i<=$row['ip_high1']; $i++)
						{
							for ($j=$row['ip_low2'];$j<=$row['ip_high2']; $j++)
							{
								for ($h=$row['ip_low3'];$h<=$row['ip_high3']; $h++)
								{
									for ($f=$row['ip_low4'];$f<=$row['ip_high4']; $f++)
									{
										$ip_to_ban=strval($i.'.'.$j.'.'.$h.'.'.$f);

										add_ip_ban($ip_to_ban);
										import_id_remap_put('ip_ban',$ip_to_ban,0);
									}
								}
							}
						}
					}
				}
			}
		}
	}

	/**
	 * Convert an IP address from phpBB hexadecimal string format.
	 *
	 * @param  string			The phpBB IP address
	 * @return IP				The normal IP address
	 */
	function _un_phpbb_ip($ip)
	{
		if (strlen($ip)<8) return '127.0.0.1';

		$_ip=strval(hexdec($ip[0].$ip[1])).'.'.strval(hexdec($ip[2].$ip[3])).'.'.strval(hexdec($ip[4].$ip[5])).'.'.strval(hexdec($ip[6].$ip[7]));
		return $_ip;
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ocf_categories($db,$table_prefix,$old_base_dir)
	{
		$rows=$db->query_select('categories');
		foreach ($rows as $row)
		{
			if (import_check_if_imported('category',strval($row['ID_CAT']))) continue;

			$title=$row['name'];
			$title=@html_entity_decode($title,ENT_QUOTES,get_charset());

			$test=$GLOBALS['FORUM_DB']->query_value_null_ok('f_categories','id',array('c_title'=>$title));
			if (!is_null($test))
			{
				import_id_remap_put('category',strval($row['ID_CAT']),$test);
				continue;
			}

			$id_new=ocf_make_category($title,'',1);

			import_id_remap_put('category',strval($row['ID_CAT']),$id_new);
		}
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ocf_forums($db,$table_prefix,$old_base_dir)
	{
		require_code('ocf_forums_action2');

		$remap_id=array();

		$rows=$db->query_select('boards');
		foreach ($rows as $row)
		{
			$remapped=import_id_remap_get('forum',strval($row['ID_BOARD']),true);
			if (!is_null($remapped))
			{
				continue;
			}

			$name=$row['name'];
			ocf_over_msn();
			$description=html_to_comcode($row['description']);
			ocf_over_local();
			$position=$row['boardOrder'];
			$post_count_increment=1;

			$parent_forum=($row['ID_PARENT']>0)?$row['ID_PARENT']:db_get_first_id();
			$cat_id=$row['ID_CAT'];

			$permission_mode=$row['permission_mode'];

			$category_id=import_id_remap_get('category',strval($cat_id),true);

			$access_mapping=array();

			$permissions_on_groups=$db->query('SELECT DISTINCT ID_GROUP FROM '.$table_prefix.'board_permissions');
			foreach ($permissions_on_groups as $gid)
			{
				$permissions=$db->query('SELECT * FROM '.$table_prefix.'board_permissions WHERE ID_GROUP='.strval((integer)$gid).' AND ID_BOARD='.strval((integer)$row['ID_BOARD']));

				$v=0;
				foreach ($permissions as $p)
				{
					if ($p['permission']=='send_topic'&&$p['addDeny']!=1&&$v<2) $v=2;
					if ($p['permission']=='post_reply_any'&&$p['addDeny']!=1&&$v<3) $v=3;
					if ($p['permission']=='poll_post'&&$p['addDeny']!=1&&$v<4) $v=4;

					$group_id=import_id_remap_get('group',strval($p['ID_GROUP']));
					$access_mapping[$group_id]=$v;
				}

			}

			$id_new=ocf_make_forum($name,$description,$category_id,$access_mapping,$parent_forum,$position,$post_count_increment,0,'');

			$remap_id[$row['ID_BOARD']]=$id_new;
			import_id_remap_put('forum',strval($row['ID_BOARD']),$id_new);
		}

		// Now we must fix parenting
		foreach ($rows as $row)
		{
			if ((!is_null($row['ID_PARENT'])) && (isset($remap_id[$row['ID_BOARD']])))
			{
				$parent_id=array_key_exists($row['ID_PARENT'],$remap_id)?$remap_id[$row['ID_PARENT']]:db_get_first_id();
				$GLOBALS['FORUM_DB']->query_update('f_forums',array('f_parent_forum'=>$parent_id),array('id'=>$remap_id[$row['ID_BOARD']]),'',1);
			}
		}
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ocf_topics($db,$table_prefix,$file_base)
	{
		$row_start=0;
		$rows=array();
		do
		{
			$rows=$db->query('SELECT * FROM '.$table_prefix.'topics t LEFT JOIN '.$table_prefix.'messages m ON t.ID_FIRST_MSG=m.ID_MSG'.(can_arbitrary_groupby()?' GROUP BY t.ID_TOPIC':''),200,$row_start);
			$rows=remove_duplicate_rows($rows,'ID_TOPIC');
			foreach ($rows as $row)
			{
				if (import_check_if_imported('topic',strval($row['ID_TOPIC']))) continue;

				$forum_id=import_id_remap_get('forum',strval($row['ID_BOARD']));

				$id_new=ocf_make_topic($forum_id,$row['subject'],'',1,($row['locked']==0)?1:0,0,0,0,NULL,NULL,false,$row['numViews']);

				import_id_remap_put('topic',strval($row['ID_TOPIC']),$id_new);
			}

			$row_start+=200;
		}
		while (count($rows)>0);
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ocf_posts($db,$table_prefix,$file_base)
	{
		global $STRICT_FILE;

		$row_start=0;
		$rows=array();
		do
		{
			$rows=$db->query('SELECT * FROM '.$table_prefix.'messages p ORDER BY p.ID_MSG',200,$row_start);
			foreach ($rows as $row)
			{
				if (import_check_if_imported('post',strval($row['ID_MSG']))) continue;

				$topic_id=import_id_remap_get('topic',strval($row['ID_TOPIC']),true);
				if (is_null($topic_id))
				{
					import_id_remap_put('post',strval($row['ID_MSG']),-1);
					continue;
				}
				$member_id=import_id_remap_get('member',strval($row['ID_MEMBER']),true);
				if (is_null($member_id)) $member_id=db_get_first_id();

				$forum_id=import_id_remap_get('forum',strval($row['ID_BOARD']),true);

				$title=$row['subject'];
				$title=@html_entity_decode($title,ENT_QUOTES,get_charset());

				ocf_over_msn();
				$post_description=html_to_comcode($row['body']);
				ocf_over_local();

				$post=$this->fix_links($post_description,$db,$table_prefix,$file_base);

				$last_edit_by=NULL;
				$last_edit_time=$row['modifiedTime'];

				$post_username=$row['posterName'];

				$id_new=ocf_make_post($topic_id,$title,$post,0,true,1,0,$post_username,$row['posterIP'],$row['posterTime'],$member_id,NULL,$last_edit_time,$last_edit_by,false,false,$forum_id,false);

				import_id_remap_put('post',strval($row['ID_MSG']),$id_new);
			}

			$row_start+=200;
		}
		while (count($rows)>0);
	}

	/**
	 * Substitution callback for 'fix_links'.
	 *
	 * @param  array				The match
	 * @return  string			The substitution string
	 */
	function _fix_links_callback_topic($m)
	{
		return 'index.php?topic='.strval(import_id_remap_get('topic',strval($m[2]),true));
	}

	/**
	 * Substitution callback for 'fix_links'.
	 *
	 * @param  array				The match
	 * @return  string			The substitution string
	 */
	function _fix_links_callback_forum($m)
	{
		return 'index.php?board='.strval(import_id_remap_get('forum',strval($m[2]),true));
	}

	/**
	 * Substitution callback for 'fix_links'.
	 *
	 * @param  array				The match
	 * @return string				The substitution string
	 */
	function _fix_links_callback_member($m)
	{
		return 'index.php?action=profile;u='.strval(import_id_remap_get('member',strval($m[2]),true));
	}

	/**
	 * Convert SMF URLs pasted in text fields into ocPortal ones.
	 *
	 * @param  string			The text field text (e.g. a post)
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 * @return string			The new text field text
	 */
	function fix_links($post,$db,$table_prefix,$file_base='')
	{
		$boardurl='';

		require($file_base.'/Settings.php');
		$old_base_url=$boardurl;

		$post=preg_replace_callback('#'.preg_quote($old_base_url).'/(index\.php\?topic=)(\d*)#',array($this,'_fix_links_callback_topic'),$post);
		$post=preg_replace_callback('#'.preg_quote($old_base_url).'/(index\.php\?board=)(\d*)#',array($this,'_fix_links_callback_forum'),$post);
		$post=preg_replace_callback('#'.preg_quote($old_base_url).'/(index\.php\?action=profile;u=)(\d*)#',array($this,'_fix_links_callback_member'),$post);
		$post=preg_replace('#:[0-9a-f]{10}#','',$post);
		return $post;
	}

	/**
	 * Convert an SMF database file to an ocPortal uploaded file (stored on disk).
	 *
	 * @param  string			The file data
	 * @param  string			The optimal filename
	 * @param  ID_TEXT		The upload type (e.g. ocf_photos)
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  string			The filename to output to
	 * @param  PATH			The base directory we are importing from
	 * @param  string			Attachment ID
	 * @return URLPATH		The URL
	 */
	function data_to_disk($data,$filename,$sections, $db,$table_prefix='', $output_filename='',$file_base='',$attachment_id='')
	{
		$boardurl='';
		$boarddir='';

		require($file_base.'/Settings.php');
		$homeurl=$boardurl;

		$forum_dir=preg_replace('#\\\\#','/',$boarddir); //full path to the forum folder

		$attachments_dir=$forum_dir.'/attachments/'; //forum attachments directory

		//start preparing the attachment file path by adding it's md5-ied filename and attachment id
		$file_stripped=strtr($filename, 'äéöûü¿¡¬√ƒ≈«»… ÀÃÕŒœ—“”‘’÷ÿŸ⁄€‹›‡·‚„‰ÂÁËÈÍÎÏÌÓÔÒÚÛÙıˆ¯˘˙˚¸˝ˇ', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy');
		$file_stripped=strtr($file_stripped, array('ﬁ'=>'TH', '˛'=>'th', '–'=>'DH', ''=>'dh', 'ﬂ'=>'ss', 'å'=>'OE', 'ú'=>'oe', '∆'=>'AE', 'Ê'=>'ae', 'µ'=>'u'));
		$file_stripped=preg_replace(array('/\s/', '/[^\w_\.\-]/'), array('_', ''), $file_stripped);
		$filename_fixed=((strlen($attachment_id)>0)?($attachment_id.'_'.str_replace('.','_',$file_stripped).md5($file_stripped)):(str_replace('.','_',$file_stripped).md5($file_stripped)));
		$file_path=$attachments_dir.$filename_fixed;

		$data=($data=='')?@file_get_contents($file_path):$data;
		$filename=($output_filename=='')?$filename_fixed:$output_filename;

		$filename=find_derivative_filename('uploads/'.$sections,$filename);
		$path=get_custom_file_base().'/uploads/'.$sections.'/'.$filename;

		$myfile=@fopen($path,'wb') OR warn_exit(do_lang_tempcode('WRITE_ERROR',escape_html('uploads/'.$sections.'/'.$filename)));
		fwrite($myfile,$data);
		fclose($myfile);
		fix_permissions($path);
		sync_file($path);

		$url='uploads/'.$sections.'/'.$filename;

		return $url;
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ocf_post_files($db,$table_prefix,$file_base)
	{
		global $STRICT_FILE;
		require_code('attachments2');
		require_code('attachments3');

		$row_start=0;
		$rows=array();
		do
		{
			$rows=$db->query('SELECT * FROM '.$table_prefix.'attachments a JOIN '.$table_prefix.'messages m ON a.ID_MSG=m.ID_MSG WHERE a.ID_MSG<>0'.(can_arbitrary_groupby()?' GROUP BY ID_ATTACH':''),200,$row_start);
			$rows=remove_duplicate_rows($rows,'ID_ATTACH');
			foreach ($rows as $row)
			{
				if (import_check_if_imported('post_files',strval($row['ID_ATTACH']))) continue;

				$post_id=import_id_remap_get('post',strval($row['ID_MSG']));

				$post_row=$GLOBALS['FORUM_DB']->query_select('f_posts p LEFT JOIN '.$GLOBALS['FORUM_DB']->get_table_prefix().'translate t ON p.p_post=t.id',array('p_time','text_original','p_poster','p_post'),array('p.id'=>$post_id),'',1);
				if (!array_key_exists(0,$post_row))
				{
					import_id_remap_put('post_files',strval($row['ID_ATTACH']),1);
					continue; // Orphaned post
				}
				$post=$post_row[0]['text_original'];
				$lang_id=$post_row[0]['p_post'];
				$member_id=$post_row[0]['p_poster'];

				$url=$this->data_to_disk('',$row['filename'],'attachments',$db,$table_prefix, '',$file_base,$row['ID_ATTACH']);
				$a_id=$GLOBALS['SITE_DB']->query_insert('attachments',array('a_member_id'=>$member_id,'a_file_size'=>$row['size'],'a_url'=>$url,'a_thumb_url'=>$url,'a_original_filename'=>$row['filename'],'a_num_downloads'=>$row['downloads'],'a_last_downloaded_time'=>NULL,'a_add_time'=>$row['posterTime'],'a_description'=>''),true);

				$GLOBALS['SITE_DB']->query_insert('attachment_refs',array('r_referer_type'=>'ocf_post','r_referer_id'=>strval($post_id),'a_id'=>$a_id));
				$post.="\n\n".'[attachment]'.strval($a_id).'[/attachment]';

				ocf_over_msn();
				update_lang_comcode_attachments($lang_id,$post,'ocf_post',strval($post_id));
				ocf_over_local();

				import_id_remap_put('post_files',strval($row['ID_ATTACH']),1);
			}

			$row_start+=200;
		}
		while (count($rows)>0);
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ocf_polls_and_votes($db,$table_prefix,$file_base)
	{
		$rows=$db->query('SELECT * FROM '.$table_prefix.'polls');
		foreach ($rows as $row)
		{
			if (import_check_if_imported('poll',strval($row['ID_POLL']))) continue;

			$poll_topic_id=$db->query('SELECT ID_TOPIC FROM '.$table_prefix.'topics WHERE ID_POLL='.strval($row['ID_POLL']));
			if (!isset($poll_topic_id[0]['ID_TOPIC'])) continue;
			$poll_topic_id=$poll_topic_id[0]['ID_TOPIC'];


			$topic_id=import_id_remap_get('topic',strval($poll_topic_id),true);
			if (is_null($topic_id))
			{
				import_id_remap_put('poll',strval($row['ID_POLL']),-1);
				continue;
			}

			$is_open=($row['expireTime']==0||$row['expireTime']>time())?1:0;

			$answers=array();
			$poll_choices=$db->query('SELECT * FROM '.$table_prefix.'poll_choices WHERE ID_POLL='.strval($row['ID_POLL']));

			$answers_array=array();
			foreach($poll_choices as $key=>$value)
			{
				$answers_array[]=$value['label'];
			}

			$answer_map=array();
			$maximum=0;
			foreach ($answers_array as $key=>$answer)
			{
				$answer_map[$key]=$poll_choices[$key]['votes'];
				$answers[$key]=$answer;
				$maximum+=$poll_choices[$key]['votes'];
			}

			$rows2=$db->query('SELECT * FROM '.$table_prefix.'log_polls WHERE ID_POLL='.strval($row['ID_POLL']));
			foreach ($rows2 as $row2)
			{
				$row2['ID_MEMBER']=import_id_remap_get('member',strval($row2['ID_MEMBER']),true);
			}

			$id_new=ocf_make_poll($topic_id,$row['question'],0,$is_open,1,$maximum,0,$answers,false);

			$answers=collapse_1d_complexity('id',$GLOBALS['FORUM_DB']->query_select('f_poll_answers',array('id'),array('pa_poll_id'=>$id_new)));

			foreach ($rows2 as $row2)
			{
				$member_id=$row2['ID_MEMBER'];
				if ((!is_null($member_id)) && ($member_id!=0))
				{
					$answer=$answers[strval($row2['ID_CHOICE'])];

					$GLOBALS['FORUM_DB']->query_insert('f_poll_votes',array('pv_poll_id'=>$id_new,'pv_member_id'=>$member_id,'pv_answer_id'=>$answer));
				}
			}

			import_id_remap_put('poll',strval($row['ID_POLL']),$id_new);
		}
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_ocf_personal_topics($db,$table_prefix,$old_base_dir)
	{
		$rows=$db->query('SELECT * FROM '.$table_prefix.'personal_messages p LEFT JOIN '.$table_prefix.'pm_recipients r ON p.ID_PM=r.ID_PM ORDER BY msgtime');

		// Group them up into what will become topics
		$groups=array();
		foreach ($rows as $row)
		{
			// Do some fiddling around for duplication
			if ($row['ID_MEMBER_FROM']>$row['ID_MEMBER'])
			{
				$a=$row['ID_MEMBER'];
				$b=$row['ID_MEMBER_FROM'];
			} else
			{
				$a=$row['ID_MEMBER_FROM'];
				$b=$row['ID_MEMBER'];
			}
			$row['subject']=str_replace('Re: ','',$row['subject']);
			$groups[strval($a).':'.strval($b).':'.$row['subject']][]=$row;
		}

		$msg_id=0;
		// Import topics
		foreach ($groups as $group)
		{
			$row=$group[0];
			$msg_id++;

			if (import_check_if_imported('pt',strval($row['ID_PM']))) continue;

			// Create topic
			$from_id=import_id_remap_get('member',strval($row['ID_MEMBER_FROM']),true);
			if (is_null($from_id)) $from_id=$GLOBALS['OCF_DRIVER']->get_guest_id();
			$to_id=import_id_remap_get('member',strval($row['ID_MEMBER']),true);
			if (is_null($to_id)) $to_id=$GLOBALS['OCF_DRIVER']->get_guest_id();
			$topic_id=ocf_make_topic(NULL,'','',1,1,0,0,0,$from_id,$to_id,false);

			$first_post=true;
			foreach ($group as $_post)
			{
				if ($first_post)
				{
					$title=$row['subject'];
				} else $title='';

				$title=@html_entity_decode($title,ENT_QUOTES,get_charset());

				ocf_over_msn();
				$post_description=html_to_comcode($_post['body']);
				ocf_over_local();

				$post=$this->fix_links($post_description,$db,$table_prefix,$old_base_dir);
				$validated=1;
				$from_id=import_id_remap_get('member',strval($_post['ID_MEMBER_FROM']),true);
				if (is_null($from_id)) $from_id=$GLOBALS['OCF_DRIVER']->get_guest_id();
				$poster_name_if_guest=$GLOBALS['OCF_DRIVER']->get_username($from_id);
				$ip_address='';
				$time=$_post['msgtime'];
				$poster=$from_id;
				$last_edit_time=NULL;
				$last_edit_by=NULL;

				ocf_make_post($topic_id,$title,$post,0,$first_post,$validated,0,$poster_name_if_guest,$ip_address,$time,$poster,NULL,$last_edit_time,$last_edit_by,false,false,NULL,false);
				$first_post=false;
			}

			import_id_remap_put('pt',strval($row['ID_PM']),$topic_id);
		}
	}

	/**
	 * Convert a SMF topic icon code into a standard ocPortal theme image code.
	 *
	 * @param  integer		VB code
	 * @return ID_TEXT		ocPortal code
	 */
	function convert_topic_emoticon($iconid)
	{
		switch ($iconid)
		{
			case 1:
				return 'ocf_emoticons/smile';
			case 2:
				return 'ocf_emoticons/wink';
			case 3:
				return 'ocf_emoticons/cheeky';
			case 4:
				return 'ocf_emoticons/grin';
			case 5:
				return 'ocf_emoticons/angry';
			case 6:
				return 'ocf_emoticons/sad';
			case 7:
				return 'ocf_emoticons/shocked';
			case 8:
				return 'ocf_emoticons/cool';
			case 10:
				return 'ocf_emoticons/rolleyes';
			case 13:
				return 'ocf_emoticons/shutup';
			case 14:
				return 'ocf_emoticons/confused';
			case 15:
				return 'ocf_emoticons/kiss';
			case 16:
				return 'ocf_emoticons/cry';
			case 17:
				return 'ocf_emoticons/devil';
		}
		return '';
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_notifications($db,$table_prefix,$file_base)
	{
		require_code('notifications');

		$row_start=0;
		$rows=array();
		do
		{
			$rows=$db->query('SELECT * FROM '.$table_prefix.'log_notify WHERE ID_TOPIC<>0',200,$row_start);
			foreach ($rows as $row)
			{
				if (import_check_if_imported('topic_notification',strval($row['ID_TOPIC']).'-'.strval($row['ID_MEMBER']))) continue;

				$member_id=import_id_remap_get('member',strval($row['ID_MEMBER']),true);
				if (is_null($member_id)) continue;
				$topic_id=import_id_remap_get('topic',strval($row['ID_TOPIC']),true);
				if (is_null($topic_id)) continue;
				enable_notifications('ocf_topic',strval($topic_id),$member_id);

				import_id_remap_put('topic_notification',strval($row['ID_TOPIC']).'-'.strval($row['ID_MEMBER']),1);
			}

			$row_start+=200;
		}
		while (count($rows)>0);
	}

	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_wordfilter($db,$table_prefix,$file_base)
	{
		$rows=$db->query('SELECT * FROM '.$table_prefix.'settings WHERE '.db_string_equal_to('variable','censor_vulgar').' OR '.db_string_equal_to('variable','censor_proper'));

		$censor_vulgar=array();
		$censor_proper=array();
		foreach ($rows as $row)
		{
			if ($row['variable']=='censor_vulgar')
			{
				$censor_vulgar=preg_split('/[\n\r]+/',$row['value']);
			} else
			{
				$censor_proper=preg_split('/[\n\r]+/',$row['value']);
			}
		}

		foreach ($censor_vulgar as $key=>$row)
		{
			add_wordfilter_word($censor_vulgar[$key],array_key_exists($key,$censor_proper)?$censor_proper[$key]:'');
		}
	}


	/**
	 * Standard import function.
	 *
	 * @param  object			The DB connection to import from
	 * @param  string			The table prefix the target prefix is using
	 * @param  PATH			The base directory we are importing from
	 */
	function import_calendar($db,$table_prefix,$file_base)
	{
		require_code('calendar2');

		$rows=$db->query_select('calendar');
		foreach ($rows as $row)
		{
			if (import_check_if_imported('event',strval($row['ID_EVENT']))) continue;

			$submitter=import_id_remap_get('member',strval($row['ID_MEMBER']),true);
			if (is_null($submitter)) $submitter=$GLOBALS['OCF_DRIVER']->get_guest_id();

			$recurrence='none';
			$recurrences=NULL;


			$days=intval(floor((strtotime($row['endDate']) - strtotime($row['startDate'])) / (60 * 60 * 24))); //Max 7 days in SMF
			if ($days==0)
			{
				$recurrence='daily 1';
			} else
			{
				$recurrence='daily ';
				for ($i=1;$i<=$days;$i++)
				{
					$recurrence.='1';
				}
			}

			$start_hour=0;
			$start_minute=0;
			list($start_year,$start_month,$start_day)=array_map('intval',explode('-',$row['eventDate']));
			list($end_year,$end_month,$end_day,$end_hour,$end_minute)=array($start_year,$start_month,$start_day,$start_hour,$start_minute);

			$description='';
			if ($row['ID_TOPIC']!=0)
			{
				$messages=$db->query('SELECT * FROM '.$table_prefix.'messages WHERE ID_TOPIC='.strval($row['ID_TOPIC']).' ORDER BY ID_TOPIC ASC');
				ocf_over_msn();
				$description=(isset($messages[0]['body'])&&($messages[0]['body']!=''))?html_to_comcode($messages[0]['body']):'';
				ocf_over_local();
			}

			ocf_over_msn();
			$id_new=add_calendar_event(db_get_first_id()+1,$recurrence,$recurrences,0,$row['title'],$description,3,1,$start_year,$start_month,$start_day,'day_of_month',$start_hour,$start_minute,$end_year,$end_month,$end_day,'day_of_month',$end_hour,$end_minute,NULL,1,1,1,1,1,'',$submitter);
			ocf_over_local();

			import_id_remap_put('event',strval($row['ID_EVENT']),$id_new);
		}


		$rows=array();
		$rows=$db->query_select('calendar_holidays');
		foreach ($rows as $row)
		{
			if (import_check_if_imported('event',strval($row['ID_HOLIDAY']))) continue;

			$submitter=$GLOBALS['OCF_DRIVER']->get_guest_id();

			$recurrence='none';
			$recurrences=NULL;


			list($start_year,$start_month,$start_day,$start_hour,$start_minute)=array_map('intval',explode('-',date('Y-m-d-h-i',strtotime($row['eventDate']))));
			list($end_year,$end_month,$end_day,$end_hour,$end_minute)=array_map('intval',explode('-',date('Y-m-d-h-i',strtotime($row['eventDate']))));

			ocf_over_msn();
			$id_new=add_calendar_event(db_get_first_id()+1,$recurrence,$recurrences,0,$row['title'],$row['title'],3,1,$start_year,$start_month,$start_day,'day_of_month',$start_hour,$start_minute,$end_year,$end_month,$end_day,'day_of_month',$end_hour,$end_minute,NULL,1,1,1,1,1,'',$submitter);
			ocf_over_local();

			import_id_remap_put('event',strval($row['ID_HOLIDAY']),$id_new);
		}
	}

}
