<?php
/**
* Class for managing upgrades
* @package upgrade
*/
class Upgrade_Factory
{
	/**
	* @var array Upgrade steps - the steps of upgrade to perform. Index is the version you are going to
	*/
	var $steps = array(
		'2005' => array (
			'create_table_categoryassociations',
			'create_table_ratings',
			'create_table_submittedquestions',
			'create_table_users',
			'create_column_categories_catdesc',
			'create_column_categories_catvisits',
			'create_column_categories_catpass',
			'create_column_categories_caticon',
			'create_column_questions_qrelatedquestions',
			'create_column_questions_qsortorder',
			'create_column_questions_qkeywords',
			'create_column_questions_quserid',
			'create_column_questions_qviews',
			'create_column_questions_qpositivevotes',
			'create_column_questions_qnegativevotes',
			'create_column_questions_qscore',
			'create_column_questions_qemailed',
			'create_column_questions_qdetectrelatedquestions',
			'move_attachments_from_db_to_file',
			'create_admin_user',
			'populate_categoryassociations_table',
		),

		'NX2' => array (
			'remove_dupe_glossary',
			'remove_dupe_users',
			'create_groups_table',
			'create_members_table',
			'create_questions_history_table',
			'create_questions_metadescription_column',
			'create_ratings_ratedat_column',
			'create_users_forgotpasscode_column',
			'create_searchhistory_table',
			'create_subscribers_table',
			'drop_attachments_table',
			'drop_categoryassociations_pk_recordid_column',
			'drop_permissions_table',
			'drop_questions_qnumviews_column',
			'drop_questions_qparentcatid_column',
			'drop_users_userroot_column',
			'rename_column_categories_catdesc_description',
			'rename_column_categories_cateparentid_parentid',
			'rename_column_categories_caticon_icon',
			'rename_column_categories_catname_name',
			'rename_column_categories_catpass_pass',
			'rename_column_categories_catvisits_visits',
			'rename_column_categories_pk_categoryid_categoryid',
			'rename_column_categoryassociations_categoryid_categoryid',
			'rename_column_categoryassociations_questionid_questionid',
			'rename_column_comments_ccomment_comment',
			'rename_column_comments_cdateadded_posted',
			'rename_column_comments_cemail_email',
			'rename_column_comments_cquestid_questionid',
			'rename_column_comments_cstatus_status',
			'rename_column_comments_cusername_name',
			'rename_column_comments_pk_commentid_commentid',
			'rename_column_glossary_glossdesc_description',
			'rename_column_glossary_glossword_word',
			'rename_column_glossary_pk_glossaryid_glossaryid',
			'rename_column_questions_pk_questid_questionid',
			'rename_column_questions_qanswer_answer',
			'rename_column_questions_qdatelastupdated_lastupdated',
			'rename_column_questions_qdetectrelatedquestions_detectrelated',
			'rename_column_questions_qemailed_emailed',
			'rename_column_questions_qkeywords_metakeywords',
			'rename_column_questions_qnegativevotes_negvotes',
			'rename_column_questions_qpositivevotes_posvotes',
			'rename_column_questions_qrelatedquestions_related',
			'rename_column_questions_qscore_score',
			'rename_column_questions_qsortorder_sortorder',
			'rename_column_questions_qtitle_title',
			'rename_column_questions_quserid_userid',
			'rename_column_questions_qviews_views',
			'rename_column_questions_qvisible_visible',
			'rename_column_ratings_pk_rateid_rateid',
			'rename_column_ratings_rip_ip',
			'rename_column_ratings_rquestionid_questionid',
			'rename_column_submittedquestions_pk_squestid_subquestid',
			'rename_column_submittedquestions_sdate_posted',
			'rename_column_submittedquestions_sfromemail_email',
			'rename_column_submittedquestions_sfromname_name',
			'rename_column_submittedquestions_smessage_message',
			'rename_column_submittedquestions_ssubject_subject',
			'rename_column_users_pk_userid_userid',
			'rename_column_users_useremail_email',
			'rename_column_users_userfirstname_firstname',
			'rename_column_users_userlastname_lastname',
			'rename_column_users_username_username',
			'rename_column_users_userpass_pass',
			'rename_column_users_userstatus_status',
			'create_idx_a_pk',
			'create_idx_a_questionid',
			'create_idx_c_name',
			'create_idx_cm_questionid',
			'create_idx_cm_status',
			'create_idx_g_word',
			'create_idx_q_lastupdated',
			'create_idx_q_score',
			'create_idx_q_sortorder',
			'create_idx_q_userid',
			'create_idx_q_vis_lastupdated',
			'create_idx_q_visible',
			'create_idx_s_questionid_email',
			'create_idx_u_status',
			'create_idx_u_username',
			'create_idx_q_ft',
		),
		
		'NX2.6' => array (
			'create_column_ratingemail',
			'create_column_ratingmessage'
		),
		
		'NX2.7' => array (
			'create_question_auth_table',
			'create_column_startdate',
			'create_column_enableexpiry',
			'create_column_expirydate_qh',
			'create_column_startdate_qh',
			'create_column_enableexpiry_qh',
			'create_column_expirydate',			
			'create_column_security',
			'create_idx_c_security',
			'migrate_category_passwords'
		),
		
		'IKM4.0' => array (
			'create_customfields_table',
			'create_customfields_data_table',
			'create_questions_customfields_table'
		),
		'IKM4.5' => array (
			'blank'
		),
		'IKM5.0.2' => array (
			'create_newss_table',
			'create_pageindex_table',
			'create_column_approvaltype',
			'create_column_catorder',
			'create_column_featured_q',
			'create_column_workflowstatus_q',
			'create_column_featured_qh',
			'create_column_workflowstatus_qh',
			'create_idx_qh_ft',
			'create_idx_ca_cqid',
			'create_column_sessionid'
		),
		'IKM5.1' => array (
			'rename_column_comments_comment_content',
			'create_column_tokencode',
			'create_userlogin_table'
		)
	);

	/**
	* @var array The release notes for the upgrade
	*/
	var $notes = array (
		'IKM5.1'	=> 'The Knowledgebase upgrade is now complete. Please click ok to proceed to the login screen. It would also be a good time to take a minute to check out the new settings available and what they do.',
		'IKM5.0.2'	=> 'The Knowledgebase upgrade is now complete. Please click ok to proceed to the login screen. It would also be a good time to take a minute to check out the new settings available and what they do.',
		'IKM4.5'	=> 'The Knowledgebase upgrade is now complete. Please click ok to proceed to the login screen. It would also be a good time to take a minute to check out the new settings available and what they do.',
		'IKM4.0'	=> 'The Knowledgebase upgrade is now complete. Please click ok to proceed to the login screen. It would also be a good time to take a minute to check out the new settings available and what they do.',
		'NX2.7' 	=> 'The Knowledgebase upgrade is now complete.\n\nPlease click ok to proceed to the login screen.\n\nYou will be required to enter your license key when you login before the other features of the control panel are available to you.\n\nIt would also be a good time to take a minute to check out the new settings available and what they do.\n\nPlease note: As of ActiveKB NX2.7, password protected categories have been replaced by the frontend user system. Any password protected categories previously in the system have been merged into this functionality. For example if you had a category called "Accounts" that had a password of "acc1", you will now have a new group called Accounts and a new user called Accounts which will be the only one who has access to this category. The password for this new user will be "acc1". So you can login via the frontend to see this.',
		'NX2.6' 	=> 'The Knowledgebase upgrade is now complete. Please click ok to proceed to the login screen. You will be required to enter your license key when you login before the other features of the control panel are available to you. It would also be a good time to take a minute to check out the new settings available and what they do.',
		'NX2' 		=> 'The Knowledgebase upgrade is now complete. Please click ok to proceed to the login screen. You will be required to enter your license key when you login before the other features of the control panel are available to you. It would also be a good time to take a minute to check out the new settings available and what they do.',
		'2005' 		=> 'The Knowledgebase upgrade is now complete. Please click ok to proceed with the login page.',
	);

	/**
	* @var string the directory with the upgrade scripts in it
	*/
	var $UpgradeDir = '';

	/**
	* @var array Anything which can be used between upgrade scripts
	*/
	var $cache = array();

	/**
	* Constructor function initializes things that can't be set in the class declaration
	*
	* @return void
	*/
	function Upgrade_Factory()
	{
		$this->UpgradeDir = dirname(__FILE__).DIRECTORY_SEPARATOR.'upgrade'.DIRECTORY_SEPARATOR;
	}

	/**
	* Run the upgrades for the target version
	*
	* @param string $version The target version to run upgrades for
	* @return void
	*/
	function RunUpgrades($version)
	{
		// Need to know the version we want to upgrade to
		if (!isset($version)) {
			return;
		}

		// Make sure the upgrade dir for this version exists
		if (!is_dir($this->UpgradeDir.$version)) {
			return;
		}

		$allPassed = true;
		$default_steps_to_run = 1;
		$steps_to_run = $default_steps_to_run;
		$passed = 0;

		$str = "";
		foreach ($this->steps[$version] as $step) {
			// We only want to run $steps_to_run steps per load so we can
			// provide feedback since we are being called via ajax
			if ($steps_to_run <= 0) {
				break;
			}
			$filename = $this->UpgradeDir.$version.DIRECTORY_SEPARATOR.$step.'.php';
			
			// We can't run an upgrade if we can't include the file
			if (!is_file($filename)) {
				if (isset($GLOBALS['databaseType'])) {
					$filename = $this->UpgradeDir.$version.DIRECTORY_SEPARATOR.$GLOBALS['databaseType'].DIRECTORY_SEPARATOR.$step.'.php';
					if (!is_file($filename)) {
						continue;
					}
				} else {
					continue;
				}
			}

			include_once($filename);
			$s = new $step();

			if (!$s->IsAlreadyUpgraded()) {
				$s->Upgrade();

				echo '<li>Running upgrade '.$step.' ... ';
				
				if (!$s->IsAlreadyUpgraded()) {
					$allPassed = false;
					echo 'Failed';
				} else {
					$passed++;
					$steps_to_run--;
					echo 'OK';
				}
				echo "</li>";
			} else {
				$passed++;
			}
		}
		
		if ($allPassed && $steps_to_run == $default_steps_to_run && $passed == count($this->steps[$version])) {

			include_once(dirname(__FILE__).'/api/class.config.php');
			$config = realpath(dirname(__FILE__).'/../admin/includes/config.php');

			if (!is_writeable($config)) {
				die("The admin/includes/config.php file is not writeable, please fix the permissions on it (chmod it to 664 or 646) and click the start button to finish the upgrade.");
			}

			$c = new Config($config);

			switch ($version) {
				case '2005':
					$c->Update('knowledgebaseName', $GLOBALS['knowledgebaseName'], false);
					$c->Update('pathToKB', $GLOBALS['pathToKB'], false);
					$c->Update('mySQLServer', $GLOBALS['mySQLServer'], false);
					$c->Update('mySQLUser', $GLOBALS['mySQLUser'], false);
					$c->Update('mySQLPass', $GLOBALS['mySQLPass'], false);
					$c->Update('mySQLDatabase', $GLOBALS['mySQLDatabase'], false);
					$c->Update('tablePrefix', $GLOBALS['tablePrefix'], false);
					$c->Update('allowVisitorComments', (($GLOBALS['allowVisitorComments'] == 1) ? 'true' : 'false' ) , false);
					$c->Update('autoApproveComments', (($GLOBALS['autoApproveComments'] == 1) ? 'true' : 'false' ) , false);
					$c->Update('enableContactPage', (($GLOBALS['enableContactPage'] == 1) ? 'true' : 'false' ) , false);
					$c->Update('useWYSIWYGEditor', (($GLOBALS['useWYSIWYGEditor'] == 1) ? 'true' : 'false' ) , false);
					$c->Update('contactEmail', (($GLOBALS['contactEmail'] == 1) ? 'true' : 'false' ) , false);

					$c->Update('isSetup', 1, false);
					$c->Update('template', 'Windows' , false);
					$c->Update('allowEmailQuestion', 'true' , false);
					$c->Update('allowPrintQuestion', 'true' , false);
					$c->Update('allowQuestionRatings', 'true' , false);
					$c->Update('sendContactEmail', 'true' , false);
					$c->Update('saveSubmittedContact', 'true' , false);
					$c->Update('cookiePrefix', 'AKB_' , false);
					$c->Update('popularSearchTerms', '' , false);
					$c->Update('skipWords', '' , false);
					$c->Update('downForMaintenance', 'false' , false);
					$c->Update('imagePath', '../images' , false);
					
					break;
				
				case 'NX2':
					$c->Update('isSetup', 'true', false);
					$c->Update('cleanUrls', 'true', false);
					$c->Update('sendCommentEmail', 'false', false);
					$c->Update('emailOnUnhelpfulRating', 'false', false);
					$c->Update('allowSubscribeToQuestions', 'false', false);
					$c->Update('useCaptchaCheck', 'true', false);
					$c->Update('defaultSearchType', 1, false);
					
					break;
				
				case 'NX2.6':
					$c->Update('isSetup', 'true', false);
					$c->Update('templateHeader', '', false);
					$c->Update('templateFooter', '', false);
					$c->Update('popularQuestionNumber', '', false);
					
					break;
				
				case 'NX2.7':
					$c->Update('isSetup', 'true', false);
					$c->Update('categoryRestrictOption', '0', false);
					$c->Update('popularQuestionNumber', '10', false);
					$c->Update('recentQuestionNumber', '10', false);
					$c->Update('enablePDFExport', 'true', false);
					
					break;
					
				case 'IKM4.0':
					$c->Update('isSetup', 'true', false);
					$c->Update('smtpDefault', 'true', false);
					$c->Update('smtpServer', '', false);
					$c->Update('smtpUsername', '', false);
					$c->Update('smtpPassword', '', false);
					$c->Update('smtpPort', '', false);
					
					break;
				case 'IKM4.5':
					$c->Update('isSetup', 'true', false);
					$c->Update('ldapUserAccountType', 'ad', false);
					$c->Update('ldapHost', '', false);
					$c->Update('ldapPort', '', false);
					$c->Update('ldapFollowReferral', '0', false);
					$c->Update('ldapVersionThree', '0', false);
					$c->Update('ldapSearchString', '', false);
					$c->Update('ldapBaseDn', '', false);
					$c->Update('ldapConnectUsername', '', false);
					$c->Update('ldapConnectPassword', '', false);
					$c->Update('ldapFirstnameMapto', '', false);
					$c->Update('ldapLastnameMapto', '', false);
					$c->Update('ldapEmailMapto', '', false);
					$c->Update('ldapRemoveUser', '0', false);
					$c->Update('ldapGroupMemberAttb', '', false);
					$c->Update('ldapDefaultAction', '', false);
					$c->Update('ldapGroupMapping', '', false);
					$c->Update('ldapEnabled', 'false', false);
					$c->Update('ldapAllowUserUpdateDetails', 'false', false);
					$c->Update('ldapEnableGroupMapping', 'false', false);
					$c->Update('ldapNegoTLS', 'false', false);
					
					break;
				case 'IKM5.0.2':
					$c->Update('isSetup', 'true', false);
					$c->Update('enableAttachmentSearch', 'false', false);
					$c->Update('enableVersionCheck', 'true', false);
					$c->Update('enableFullindexPopulation', 'true', false);
					$c->Update('indexPlugins', '', false);
					$c->Update('databaseType', 'mysql', false);
					$c->Update('featuredQuestionNumber', '10', false);
					$c->Update('newsQuestionNumber', '10', false);
					
					// checking the attachment plugin ability 
					$tempDirectory = realpath('./');
					if ($tempDirectory[strlen($tempDirectory)-1] != DIRECTORY_SEPARATOR) {
						$tempDirectory = $tempDirectory . DIRECTORY_SEPARATOR;
					}
					$tempDirectory = $tempDirectory.'tmp';
					
					$c->Update('tempDirectory', $tempDirectory, false);	//IKM5.0
					if (isset($GLOBALS['DocumentPlugins'])) {
						$plugin = '';
						$tempAvailPlugins = array();
						foreach ($GLOBALS['DocumentPlugins'] as $eachPlugin) {
							if ($eachPlugin != 'Default_Plugin') {
								unset($plugin);
								$plugin = new $eachPlugin();
								$pluginCheck = $plugin->Check();
								
								// if word check for the directory length
								if ($eachPlugin == 'External_Doc_Plugin') {
									if (substr(strtolower(PHP_OS), 0, 3) == 'win') {
										$separator = '\\';
										if (strstr($tempDirectory, '/')) {
											$separator = '/';
										}
										$tempDirectoriesName = explode($separator, $tempDirectory);
										foreach ($tempDirectoriesName as $eachDirName) {
											if (strlen($eachDirName) > TEMP_DIR_LEN) {
												$pluginCheck = false;
												break;
											}
										}
									}
								}
								
								if ($pluginCheck) {
									$tempAvailPlugins[] = $eachPlugin;
								}
							}
						}
						if (sizeof($tempAvailPlugins) > 0) {
							array_unshift($tempAvailPlugins, 'Default_Plugin');
							$c->Update('enableAttachmentSearch', 'true', false);	//IKM5.0
							$c->Update('indexPlugins', implode(',',$tempAvailPlugins), false);	//IKM5.0
						}
					}
					
					break;
				case 'IKM5.1':
					$c->Update('isSetup', 'true', false);
					$c->Update('DBVersion', $GLOBALS['databaseVersion'], false);
					$c->Update('currentLanguage', 'en', false);
					$c->Update('bannedRetried', '3', false);
					$c->Update('bannedPeriod', '5', false);
					break;

			}
			if ($c->Save()) {
				if (isset($this->notes[$version])) {
					$_SESSION['_upgrade'][$version] = $this->notes[$version];
				}				
				
				if ($version == VERSION) {
					//We're at the end of the cycle.
					die("finished");
				} else {
					//There are still more upgrade points to get through.
					die("unfinished");
				}
			} else {
				echo "I'm sorry there has been an error trying to write to your config file at admin/includes/config.php. Please make this file writeable and try again.\n\nIf you continue to have a problem please contact support at ".GetLang('hpKBSoftwareLink')."\n\nThe exact error is: ".$c->error;
			}
		}
	}

	/**
	* ShowConfirm
	*
	* Show a confirmation screen before upgrading
	*
	* @param string $target The target version to upgrade to
	*
	* @return void
	*/
	function ShowConfirm($target)
	{
		if (empty($target)) {
			return;
		}

		$GLOBALS['FormAction'] = $GLOBALS['pathToKB'].'/admin/index.php?confirm=1';
		$GLOBALS['TargetVersion'] = VERSION;
		
		$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('upgrade.factory.welcome');
		$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate('upgrade.factory.welcome');
	}

}

?>