| 45 | 45 | 		$aTablesList = array_flip($aTablesList);
 | 
  | 46 | 46 | 		$oDb = WbDatabase::getInstance();
 | 
  | 47 | 47 | 		$sPattern = addcslashes ( $oDb->TablePrefix, '%_' );
 | 
  | 48 |  | 		if(($oTables = $oDb->query( 'SHOW TABLES LIKE "'.$sPattern.'%"'))) {
 | 
  | 49 |  | 			while($aTable = $oTables->fetchRow(MYSQL_NUM)) {
 | 
  |  | 48 | 		if (($oTables = $oDb->query( 'SHOW TABLES LIKE "'.$sPattern.'%"'))) {
 | 
  |  | 49 | 			while ($aTable = $oTables->fetchRow(MYSQL_NUM)) {
 | 
  | 50 | 50 | 				$sTable =  preg_replace('/^'.preg_quote($oDb->TablePrefix, '/').'/s', '', $aTable[0]);
 | 
  | 51 |  | 				if(isset($aTablesList[$sTable])) {
 | 
  |  | 51 | 				if (isset($aTablesList[$sTable])) {
 | 
  | 52 | 52 | 					unset($aTablesList[$sTable]);
 | 
  | 53 | 53 | 				}
 | 
  | 54 | 54 | 			}
 | 
  | ... | ... |  | 
  | 64 | 64 | 	{
 | 
  | 65 | 65 | 		return self::getMissingTables($aTablesList);
 | 
  | 66 | 66 | 	}
 | 
  |  | 67 | /**
 | 
  |  | 68 |  * Sanitize and repair Pagetree links
 | 
  |  | 69 |  * @return boolean|int number of updated records or false on error
 | 
  |  | 70 |  */
 | 
  |  | 71 | 	public static function sanitizePagesTreeLinkStructure()
 | 
  |  | 72 | 	{
 | 
  |  | 73 | 		$oDb = WbDatabase::getInstance();
 | 
  |  | 74 | 		$iCounter = 0;
 | 
  |  | 75 | 		$aPages = array();
 | 
  |  | 76 | 		try {
 | 
  |  | 77 | 			$sql = 'SELECT `page_id`, `link`, `page_trail` '
 | 
  |  | 78 | 				 . 'FROM `'.$oDb->TablePrefix.'pages` '
 | 
  |  | 79 | 				 . 'ORDER BY `page_id`';
 | 
  |  | 80 | 			$oPages = $oDb->doQuery($sql);
 | 
  |  | 81 | 			// read 'page_id', 'link' and 'page_trail' from all pages
 | 
  |  | 82 | 			while ($aPage = $oPages->fetchRow(MYSQL_ASSOC)) {
 | 
  |  | 83 | 				// extact filename only from complete link
 | 
  |  | 84 | 				$aPages[$aPage['page_id']]['filename'] = preg_replace('/.*?\/([^\/]*$)/', '\1', $aPage['link']);
 | 
  |  | 85 | 				$aPages[$aPage['page_id']]['page_trail'] = $aPage['page_trail'];
 | 
  |  | 86 | 				$aPages[$aPage['page_id']]['link'] = $aPage['link'];
 | 
  |  | 87 | 			}
 | 
  |  | 88 | 			foreach ($aPages as $iKey=>$aRecord) {
 | 
  |  | 89 | 			// iterate all pages
 | 
  |  | 90 | 				$aTmp = array();
 | 
  |  | 91 | 				$aIds = explode(',', $aRecord['page_trail']);
 | 
  |  | 92 | 				// rebuild link from filenames using page_trail
 | 
  |  | 93 | 				foreach($aIds as $iId) {
 | 
  |  | 94 | 					$aTmp[] = $aPages[$iId]['filename'];
 | 
  |  | 95 | 				}
 | 
  |  | 96 | 				$sLink = '/'.implode('/', $aTmp);
 | 
  |  | 97 | 				if ($sLink != $aPages[$iKey]['link']) {
 | 
  |  | 98 | 				// update page if old link is different to new generated link
 | 
  |  | 99 | 					$sql = 'UPDATE `'.$oDb->TablePrefix.'pages` '
 | 
  |  | 100 | 						 . 'SET `link`=\''.$sLink.'\' '
 | 
  |  | 101 | 						 . 'WHERE `page_id`='.$iKey;
 | 
  |  | 102 | 					$oDb->doQuery($sql);
 | 
  |  | 103 | 					$iCounter++;
 | 
  |  | 104 | 				}
 | 
  |  | 105 | 			}
 | 
  |  | 106 | 		} catch(WbDatabaseException $e) {
 | 
  |  | 107 | 			return false;
 | 
  |  | 108 | 		}
 | 
  |  | 109 | 		return $iCounter;
 | 
  |  | 110 | 	}
 | 
  |  | 111 | /**
 | 
  |  | 112 |  *
 | 
  |  | 113 |  * @param string $sMsg Message to show
 | 
  |  | 114 |  */
 | 
  |  | 115 | 	public static function dieWithMessage($sMsg)
 | 
  |  | 116 | 	{
 | 
  |  | 117 | 		$sMsg = 'Fatal error occured during initial startup.<br /><br />'.PHP_EOL.$sMsg
 | 
  |  | 118 | 			  . '<br />'.PHP_EOL.'Please correct these errors and then '
 | 
  |  | 119 | 			  . '<a href="http://'.$_SERVER["HTTP_HOST"].$_SERVER["SCRIPT_NAME"].'" '
 | 
  |  | 120 | 			  . 'title="restart">klick here to restart the upgrade-script</a>.<br />'.PHP_EOL;
 | 
  |  | 121 | 		die($sMsg);
 | 
  |  | 122 | 	}
 | 
  |  | 123 | /**
 | 
  |  | 124 |  *
 | 
  |  | 125 |  * @param string $sAppPath path to the current installation
 | 
  |  | 126 |  * @return boolean
 | 
  |  | 127 |  */
 | 
  |  | 128 | 	public static function checkSetupFiles($sAppPath)
 | 
  |  | 129 | 	{
 | 
  |  | 130 | 		if (defined('DB_PASSWORD')) {
 | 
  |  | 131 | 		// old config.php is active
 | 
  |  | 132 | 			if (!is_writable($sAppPath.'config.php') || !is_writable($sAppPath.'config.php.new') || !is_writable($sAppPath.'setup.ini.php.new'))
 | 
  |  | 133 | 			{
 | 
  |  | 134 | 			// stop script if there's an error occured
 | 
  |  | 135 | 				$sMsg = 'Following files must exist and be writable to run upgrade:<br />'
 | 
  |  | 136 | 				      . '<ul><li>config.php</li>'.(file_exists($sAppPath.'config.php.new') ? '<li>config.php.new</li>' : '')
 | 
  |  | 137 | 				      . '<li>setup.ini.php.new</li></ul>';
 | 
  |  | 138 | 				self::dieWithMessage($sMsg);
 | 
  |  | 139 | 			} else { // ok, let's change the files now!
 | 
  |  | 140 | 				if (file_exists($aAppPath.'setup.ini.php')) {
 | 
  |  | 141 | 				// if 'setup.ini.php' exists
 | 
  |  | 142 | 					if (!is_writeable($aAppPath.'setup.ini.php')) {
 | 
  |  | 143 | 					// but it's not writable
 | 
  |  | 144 | 						$sMsg = 'The file \'setup.ini.php\' already exists but is not writeable!';
 | 
  |  | 145 | 						self::dieWithMessage($sMsg);
 | 
  |  | 146 | 					}
 | 
  |  | 147 | 				} else {
 | 
  |  | 148 | 				// try to rename 'setup.ini.php.new' into 'setup.ini.php'
 | 
  |  | 149 | 					if (!rename($aAppPath.'setup.ini.php.new', $aAppPath.'setup.ini.php')) {
 | 
  |  | 150 | 						$sMsg = 'Can not rename \''.$aAppPath.'setup.ini.php.new\' into \''.$aAppPath.'setup.ini.php\' !!<br />'
 | 
  |  | 151 | 						      . 'Create an empty file \''.$aAppPath.'setup.ini.php\' and make it writeable for the server!';
 | 
  |  | 152 | 						self::dieWithMessage($sMsg);
 | 
  |  | 153 | 					}
 | 
  |  | 154 | 				}
 | 
  |  | 155 | 			// now first read constants from old config.php
 | 
  |  | 156 | 				$sContent = file_get_contents($sAppPath.'config.php');
 | 
  |  | 157 | 				$sPattern = '/^\s*define\s*\(\s*([\'\"])(.*?)\1\s*,.*;\s*$/m';
 | 
  |  | 158 | 				if (preg_match_all($sPattern, $sContent, $aMatches)) {
 | 
  |  | 159 | 				// get all already defined consts
 | 
  |  | 160 | 					$aAllConsts = get_defined_constants(true);
 | 
  |  | 161 | 					$aSetupConsts = array();
 | 
  |  | 162 | 				// collect the needed values from defined consts
 | 
  |  | 163 | 					foreach($aMatches[2] as $sConstName) {
 | 
  |  | 164 | 						$aSetupConsts[$sConstName] = (isset($aAllConsts['user'][$sConstName]) ? $aAllConsts['user'][$sConstName] : '');
 | 
  |  | 165 | 					}
 | 
  |  | 166 | 				// try to sanitize available values
 | 
  |  | 167 | 					$aSetupConsts['DB_TYPE'] = ((isset($aSetupConsts['DB_TYPE']) && $aSetupConsts['DB_TYPE'] != '') ? $aSetupConsts['DB_TYPE'] : 'mysql');
 | 
  |  | 168 | 					$aSetupConsts['DB_PORT'] = ((isset($aSetupConsts['DB_PORT']) && $aSetupConsts['DB_PORT'] != '') ? $aSetupConsts['DB_PORT'] : '3306');
 | 
  |  | 169 | 					$aSetupConsts['DB_CHARSET'] = (isset($aSetupConsts['DB_CHARSET']) ? $aSetupConsts['DB_CHARSET'] : '');
 | 
  |  | 170 | 					$aSetupConsts['DB_CHARSET'] = preg_replace('/[^0-9a-z]*/i', '', $aSetupConsts['DB_CHARSET']);
 | 
  |  | 171 | 					$aSetupConsts['TABLE_PREFIX'] = (isset($aSetupConsts['TABLE_PREFIX']) ? $aSetupConsts['TABLE_PREFIX'] : '');
 | 
  |  | 172 | 					$aSetupConsts['ADMIN_DIRECTORY'] = trim(str_replace('\\', '/', preg_replace('/^'.preg_quote(WB_PATH, '/').'/', '', ADMIN_PATH)), '/').'/';
 | 
  |  | 173 | 					$aSetupConsts['WB_URL'] = rtrim(str_replace('\\', '/', WB_URL), '/').'/';
 | 
  |  | 174 | 				// Try and write settings to config file
 | 
  |  | 175 | 					if (writeSetupIni($sAppPath, $aSetupConsts)) {
 | 
  |  | 176 | 						if (writeConfig($sAppPath)) {
 | 
  |  | 177 | 							return true;
 | 
  |  | 178 | 						} else {
 | 
  |  | 179 | 							$sMsg ='Error writing \''.$sAppPath.'config.php\'!';
 | 
  |  | 180 | 						}
 | 
  |  | 181 | 					} else {
 | 
  |  | 182 | 						$sMsg ='Error writing \''.$sAppPath.'setup.ini.php\'!';
 | 
  |  | 183 | 					}
 | 
  |  | 184 | 				} else {
 | 
  |  | 185 | 					$sMsg = 'No valid content found in \''.$sAppPath.'config.php\'!';
 | 
  |  | 186 | 				}
 | 
  |  | 187 | 				self::dieWithMessage($sMsg);
 | 
  |  | 188 | 			}
 | 
  |  | 189 | 		} else {
 | 
  |  | 190 | 			$sFileContent = file_get_contents($sAppPath.'config.php');
 | 
  |  | 191 | 			if (preg_match('/\s*define\s*\(.*\)\s*;/i', $sFileContent)) {
 | 
  |  | 192 | 			// if config.php does not contain any defines
 | 
  |  | 193 | 				if (is_writable($sAppPath.'config.php')) {
 | 
  |  | 194 | 				// overwrite config.php with default content for compatibility
 | 
  |  | 195 | 					if (self::writeConfig($sAppPath.'config.php')) {
 | 
  |  | 196 | 						return true;
 | 
  |  | 197 | 					} else  {
 | 
  |  | 198 | 						$sMsg ='Error writing \''.$sAppPath.'config.php\'!';
 | 
  |  | 199 | 					}
 | 
  |  | 200 | 				} else {
 | 
  |  | 201 | 					$sMsg ='File is not writable \''.$sAppPath.'config.php\'!';
 | 
  |  | 202 | 				}
 | 
  |  | 203 | 				self::dieWithMessage($sMsg);
 | 
  |  | 204 | 			}
 | 
  |  | 205 | 		}
 | 
  |  | 206 | 	}
 | 
  |  | 207 | /**
 | 
  |  | 208 |  *
 | 
  |  | 209 |  * @param string $sAppPath the path where setup.ini.php is located
 | 
  |  | 210 |  * @param array  $aSetupValues
 | 
  |  | 211 |  * @return boolean
 | 
  |  | 212 |  */
 | 
  |  | 213 | 	public static function writeSetupIni($sAppPath, array $aSetupValues)
 | 
  |  | 214 | 	{
 | 
  |  | 215 | 		$sSetupContent =
 | 
  |  | 216 | 			";<?php die('sorry, illegal file access'); ?>#####\n"
 | 
  |  | 217 | 		   .";################################################\n"
 | 
  |  | 218 | 		   ."; WebsiteBaker configuration file\n"
 | 
  |  | 219 | 		   ."; auto generated ".date('Y-m-d h:i:s A e ')."\n"
 | 
  |  | 220 | 		   .";################################################\n"
 | 
  |  | 221 | 		   ."[Constants]\n"
 | 
  |  | 222 | 		   ."DEBUG   = false\n"
 | 
  |  | 223 | 		   ."AppUrl  = \"".$aSetupValues['WB_URL']."\"\n"
 | 
  |  | 224 | 		   ."AcpDir  = \"".$aSetupValues['ADMIN_DIRECTORY']."\"\n"
 | 
  |  | 225 | 		   .";##########\n"
 | 
  |  | 226 | 		   ."[DataBase]\n"
 | 
  |  | 227 | 		   ."type    = \"".$aSetupValues['DB_TYPE']."\"\n"
 | 
  |  | 228 | 		   ."user    = \"".$aSetupValues['DB_USERNAME']."\"\n"
 | 
  |  | 229 | 		   ."pass    = \"".$aSetupValues['DB_PASSWORD']."\"\n"
 | 
  |  | 230 | 		   ."host    = \"".$aSetupValues['DB_HOST']."\"\n"
 | 
  |  | 231 | 		   ."port    = \"".$aSetupValues['DB_PORT']."3306\"\n"
 | 
  |  | 232 | 		   ."name    = \"".$aSetupValues['DB_NAME']."\"\n"
 | 
  |  | 233 | 		   ."charset = \"".$aSetupValues['DB_CHARSET']."\"\n"
 | 
  |  | 234 | 		   ."table_prefix = \"".$aSetupValues['TABLE_PREFIX']."\"\n"
 | 
  |  | 235 | 		   .";\n"
 | 
  |  | 236 | 		   .";################################################\n";
 | 
  |  | 237 | 		$sSetupFile = $sAppPath.'setup.ini.php';
 | 
  |  | 238 | 		if (file_put_contents($sSetupFile, $sSetupContent)) {
 | 
  |  | 239 | 			return true;
 | 
  |  | 240 | 		}
 | 
  |  | 241 | 		return false;
 | 
  |  | 242 | 	}
 | 
  |  | 243 | /**
 | 
  |  | 244 |  * 
 | 
  |  | 245 |  * @param string $sAppPath the path where config.php is located
 | 
  |  | 246 |  * @return boolean
 | 
  |  | 247 |  */
 | 
  |  | 248 | 	public static function writeConfig($sAppPath)
 | 
  |  | 249 | 	{
 | 
  |  | 250 | 		$sConfigContent = "<?php\n"
 | 
  |  | 251 | 			."/* this file is for backward compatibility only */\n"
 | 
  |  | 252 | 			."/* never put any code in this file! */\n"
 | 
  |  | 253 | 			."include_once(dirname(__FILE__).'/framework/initialize.php');\n";
 | 
  |  | 254 | 		$sConfigFile = $sAppPath.'config.php';
 | 
  |  | 255 | 		if (file_put_contents($sConfigFile, $sConfigContent)) {
 | 
  |  | 256 | 			return true;
 | 
  |  | 257 | 		}
 | 
  |  | 258 | 		return false;
 | 
  |  | 259 | 	}
 | 
  | 67 | 260 | 
 | 
  | 68 |  | 
 | 
  | 69 | 261 | } // end of class UpgradeHelper
 | 
  | 70 | 262 | 
 | 
 
! upgrade-script:: now repairs mismatched pagelinks from older versions
! upgrade-script:: /temp/TranslationTable/cache/ will be deleted now during upgrade
+ UpgradeHelper::checkSetupFiles() the old config.php will be changed into setup.ini.php now.