Index: branches/2.8.x/CHANGELOG
===================================================================
--- branches/2.8.x/CHANGELOG	(revision 1419)
+++ branches/2.8.x/CHANGELOG	(revision 1420)
@@ -11,6 +11,8 @@
 ! = Update/Change
 
 ------------------------------------- 2.8.2 -------------------------------------
+26 Jan-2011 Build 1420 Dietmar Woellbrink (Luisehahne)
+# YGN Ethical Hacker Group (2.8.2 / 2.9.0)
 26 Jan-2011 Build 1419 Dietmar Woellbrink (Luisehahne)
 ! update rel handling FCKeditor for urls
 25 Jan-2011 Build 1418 Dietmar Woellbrink (Luisehahne)
Index: branches/2.8.x/wb/admin/interface/version.php
===================================================================
--- branches/2.8.x/wb/admin/interface/version.php	(revision 1419)
+++ branches/2.8.x/wb/admin/interface/version.php	(revision 1420)
@@ -52,6 +52,6 @@
 
 // check if defined to avoid errors during installation (redirect to admin panel fails if PHP error/warnings are enabled)
 if(!defined('VERSION')) define('VERSION', '2.8.2.RC5');
-if(!defined('REVISION')) define('REVISION', '1419');
+if(!defined('REVISION')) define('REVISION', '1420');
 
 ?>
Index: branches/2.8.x/wb/account/login_form.php
===================================================================
--- branches/2.8.x/wb/account/login_form.php	(revision 1419)
+++ branches/2.8.x/wb/account/login_form.php	(revision 1420)
@@ -1,87 +1,88 @@
-<?php
-/**
- *
- * @category        frontend
- * @package         account
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-if(!defined('WB_URL')) die(header('Location: ../../index.php'));
-
-$username_fieldname = 'username';
-$password_fieldname = 'password';
-	
-if(defined('SMART_LOGIN') AND SMART_LOGIN == 'enabled') {
-	// Generate username field name
-	$username_fieldname = 'username_';
-	$password_fieldname = 'password_';
-
-	$temp = array_merge(range('a','z'), range(0,9));
-	shuffle($temp);
-	for($i=0;$i<=7;$i++) {
-		$username_fieldname .= $temp[$i];
-		$password_fieldname .= $temp[$i];
-	}
-}
-?>
-<h1>&nbsp;Login</h1>
-&nbsp;<?php echo $thisApp->message; ?>
-<br />
-<br />
-
-<form action="<?php echo WB_URL.'/account/login.php'; ?>" method="post">
-<p style="display:none;"><input type="hidden" name="username_fieldname" value="<?php echo $username_fieldname; ?>" /></p>
-<p style="display:none;"><input type="hidden" name="password_fieldname" value="<?php echo $password_fieldname; ?>" /></p>
-<p style="display:none;"><input type="hidden" name="redirect" value="<?php echo $thisApp->redirect_url;?>" /></p>
-
-<table cellpadding="5" cellspacing="0" border="0" width="90%">
-<tr>
-	<td style="width:100px"><?php echo $TEXT['USERNAME']; ?>:</td>
-	<td class="value_input">
-		<input type="text" name="<?php echo $username_fieldname; ?>" maxlength="30" style="width:220px;"/>
-    	<script type="text/javascript">
-    	// document.login.<?php echo $username_fieldname; ?>.focus();
-    	var ref= document.getElementById("<?php echo $username_fieldname; ?>");
-    	if (ref) ref.focus();
-    	</script>
-	</td>
-</tr>
-<tr>
-	<td style="width:100px"><?php echo $TEXT['PASSWORD']; ?>:</td>
-	<td class="value_input">
-		<input type="password" name="<?php echo $password_fieldname; ?>" maxlength="30" style="width:220px;"/>
-	</td>
-</tr>
-<?php if($username_fieldname != 'username') { ?>
-<tr>
-	<td>&nbsp;</td>
-	<td>
-		<input type="checkbox" name="remember" id="remember" value="true"/>
-		<label for="remember"><?php echo $TEXT['REMEMBER_ME']; ?></label>
-	</td>
-</tr>
-<?php } ?>
-<tr>
-	<td>&nbsp;</td>
-	<td>
-		<input type="submit" name="submit" value="<?php echo $TEXT['LOGIN']; ?>"  />
-		<input type="reset" name="reset" value="<?php echo $TEXT['RESET']; ?>"  />
-	</td>
-</tr>
-</table>
-
-</form>
-
-<br />
-
+<?php
+/**
+ *
+ * @category        frontend
+ * @package         account
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+$username_fieldname = 'username';
+$password_fieldname = 'password';
+	
+if(defined('SMART_LOGIN') AND SMART_LOGIN == 'enabled') {
+	// Generate username field name
+	$username_fieldname = 'username_';
+	$password_fieldname = 'password_';
+
+	$temp = array_merge(range('a','z'), range(0,9));
+	shuffle($temp);
+	for($i=0;$i<=7;$i++) {
+		$username_fieldname .= $temp[$i];
+		$password_fieldname .= $temp[$i];
+	}
+}
+?>
+<h1>&nbsp;Login</h1>
+&nbsp;<?php echo $thisApp->message; ?>
+<br />
+<br />
+
+<form action="<?php echo WB_URL.'/account/login.php'; ?>" method="post">
+<p style="display:none;"><input type="hidden" name="username_fieldname" value="<?php echo $username_fieldname; ?>" /></p>
+<p style="display:none;"><input type="hidden" name="password_fieldname" value="<?php echo $password_fieldname; ?>" /></p>
+<p style="display:none;"><input type="hidden" name="redirect" value="<?php echo $thisApp->redirect_url;?>" /></p>
+
+<table cellpadding="5" cellspacing="0" border="0" width="90%">
+<tr>
+	<td style="width:100px"><?php echo $TEXT['USERNAME']; ?>:</td>
+	<td class="value_input">
+		<input type="text" name="<?php echo $username_fieldname; ?>" maxlength="30" style="width:220px;"/>
+    	<script type="text/javascript">
+    	// document.login.<?php echo $username_fieldname; ?>.focus();
+    	var ref= document.getElementById("<?php echo $username_fieldname; ?>");
+    	if (ref) ref.focus();
+    	</script>
+	</td>
+</tr>
+<tr>
+	<td style="width:100px"><?php echo $TEXT['PASSWORD']; ?>:</td>
+	<td class="value_input">
+		<input type="password" name="<?php echo $password_fieldname; ?>" maxlength="30" style="width:220px;"/>
+	</td>
+</tr>
+<?php if($username_fieldname != 'username') { ?>
+<tr>
+	<td>&nbsp;</td>
+	<td>
+		<input type="checkbox" name="remember" id="remember" value="true"/>
+		<label for="remember"><?php echo $TEXT['REMEMBER_ME']; ?></label>
+	</td>
+</tr>
+<?php } ?>
+<tr>
+	<td>&nbsp;</td>
+	<td>
+		<input type="submit" name="submit" value="<?php echo $TEXT['LOGIN']; ?>"  />
+		<input type="reset" name="reset" value="<?php echo $TEXT['RESET']; ?>"  />
+	</td>
+</tr>
+</table>
+
+</form>
+
+<br />
+
 <a href="<?php echo WB_URL; ?>/account/forgot.php"><?php echo $TEXT['FORGOTTEN_DETAILS']; ?></a>
\ No newline at end of file
Index: branches/2.8.x/wb/account/password.php
===================================================================
--- branches/2.8.x/wb/account/password.php	(revision 1419)
+++ branches/2.8.x/wb/account/password.php	(revision 1420)
@@ -16,10 +16,8 @@
  *
  */
 
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 // Get the values entered
 $current_password = $_POST['current_password'];
Index: branches/2.8.x/wb/account/forgot_form.php
===================================================================
--- branches/2.8.x/wb/account/forgot_form.php	(revision 1419)
+++ branches/2.8.x/wb/account/forgot_form.php	(revision 1420)
@@ -1,137 +1,135 @@
-<?php
-/**
- *
- * @category        frontend
- * @package         account
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-if(!defined('WB_URL')) {
-	header('Location: ../pages/index.php');
-	exit(0);
-}
-
-// Create new database object
-// $database = new database();
-
-// Check if the user has already submitted the form, otherwise show it
-if(isset($_POST['email']) && $_POST['email'] != "" &&
-    preg_match("/([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}/i", $_POST['email'])) {
-	$email = strip_tags($_POST['email']);
-	
-	// Check if the email exists in the database
-	$query = "SELECT user_id,username,display_name,email,last_reset,password FROM ".TABLE_PREFIX."users WHERE email = '".$wb->add_slashes($_POST['email'])."'";
-	$results = $database->query($query);
-	if($results->numRows() > 0) {
-	
-		// Get the id, username, email, and last_reset from the above db query
-		$results_array = $results->fetchRow();
-		
-		// Check if the password has been reset in the last 2 hours
-		$last_reset = $results_array['last_reset'];
-		$time_diff = time()-$last_reset; // Time since last reset in seconds
-		$time_diff = $time_diff/60/60; // Time since last reset in hours
-		if($time_diff < 2) {
-			
-			// Tell the user that their password cannot be reset more than once per hour
-			$message = $MESSAGE['FORGOT_PASS']['ALREADY_RESET'];
-			
-		} else {
-		
-			$old_pass = $results_array['password'];
-
-			// Generate a random password then update the database with it
-			$new_pass = '';
-			$salt = "abchefghjkmnpqrstuvwxyz0123456789";
-			srand((double)microtime()*1000000);
-			$i = 0;
-			while ($i <= 7) {
-				$num = rand() % 33;
-				$tmp = substr($salt, $num, 1);
-				$new_pass = $new_pass . $tmp;
-				$i++;
-			}
-			$database->query("UPDATE ".TABLE_PREFIX."users SET password = '".md5($new_pass)."', last_reset = '".time()."' WHERE user_id = '".$results_array['user_id']."'");
-			
-			if($database->is_error()) {
-				// Error updating database
-				$message = $database->get_error();
-			} else {
-				// Setup email to send
-				$mail_to = $email;
-				$mail_subject = $MESSAGE['SIGNUP2']['SUBJECT_LOGIN_INFO'];
-
-				// Replace placeholders from language variable with values
-				$search = array('{LOGIN_DISPLAY_NAME}', '{LOGIN_WEBSITE_TITLE}', '{LOGIN_NAME}', '{LOGIN_PASSWORD}');
-				$replace = array($results_array['display_name'], WEBSITE_TITLE, $results_array['username'], $new_pass); 
-				$mail_message = str_replace($search, $replace, $MESSAGE['SIGNUP2']['BODY_LOGIN_FORGOT']);
-
-				// Try sending the email
-				if($wb->mail(SERVER_EMAIL,$mail_to,$mail_subject,$mail_message)) { 
-					$message = $MESSAGE['FORGOT_PASS']['PASSWORD_RESET'];
-					$display_form = false;
-				} else {
-					$database->query("UPDATE ".TABLE_PREFIX."users SET password = '".$old_pass."' WHERE user_id = '".$results_array['user_id']."'");
-					$message = $MESSAGE['FORGOT_PASS']['CANNOT_EMAIL'];
-				}
-			}
-		
-		}
-
-	} else {
-		// Email doesn't exist, so tell the user
-		$message = $MESSAGE['FORGOT_PASS']['EMAIL_NOT_FOUND'];
-	}
-	
-} else {
-	$email = '';
-}
-
-if(!isset($message)) {
-	$message = $MESSAGE['FORGOT_PASS']['NO_DATA'];
-	$message_color = '000000';
-} else {
-	$message_color = 'FF0000';
-}
-	
-?>
-<h1 style="text-align: center;"><?php echo $MENU['FORGOT']; ?></h1>
-
-<form name="forgot_pass" action="<?php echo WB_URL.'/account/forgot.php'; ?>" method="post">
-	<input type="hidden" name="url" value="{URL}" />
-		<table cellpadding="5" cellspacing="0" border="0" align="center" width="500">
-		<tr>
-			<td height="40" align="center" style="color: #<?php echo $message_color; ?>;" colspan="2">
-			<?php echo $message; ?>
-			</td>
-		</tr>
-		<?php if(!isset($display_form) OR $display_form != false) { ?>
-		<tr>
-			<td height="10" colspan="2"></td>
-		</tr>
-		<tr>
-			<td width="165" height="30" align="right"><?php echo $TEXT['EMAIL']; ?>:</td>
-			<td><input type="text" maxlength="255" name="email" value="<?php echo $email; ?>" style="width: 180px;" /></td>
-			<td><input type="submit" name="submit" value="<?php echo $TEXT['SEND_DETAILS']; ?>" style="width: 180px; font-size: 10px; color: #003366; border: 1px solid #336699; background-color: #DDDDDD; padding: 3px; text-transform: uppercase;" /></td>
-		</tr>
-<!--
-		<tr>
-			<td>&nbsp;</td>
-		</tr>
-		<tr style="display: {DISPLAY_FORM}">
-			<td height="10" colspan="2"></td>
-		</tr>
--->
-		<?php } ?>
-		</table>
+<?php
+/**
+ *
+ * @category        frontend
+ * @package         account
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+// Create new database object
+// $database = new database();
+
+// Check if the user has already submitted the form, otherwise show it
+if(isset($_POST['email']) && $_POST['email'] != "" &&
+    preg_match("/([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}/i", $_POST['email'])) {
+	$email = strip_tags($_POST['email']);
+	
+	// Check if the email exists in the database
+	$query = "SELECT user_id,username,display_name,email,last_reset,password FROM ".TABLE_PREFIX."users WHERE email = '".$wb->add_slashes($_POST['email'])."'";
+	$results = $database->query($query);
+	if($results->numRows() > 0) {
+	
+		// Get the id, username, email, and last_reset from the above db query
+		$results_array = $results->fetchRow();
+		
+		// Check if the password has been reset in the last 2 hours
+		$last_reset = $results_array['last_reset'];
+		$time_diff = time()-$last_reset; // Time since last reset in seconds
+		$time_diff = $time_diff/60/60; // Time since last reset in hours
+		if($time_diff < 2) {
+			
+			// Tell the user that their password cannot be reset more than once per hour
+			$message = $MESSAGE['FORGOT_PASS']['ALREADY_RESET'];
+			
+		} else {
+		
+			$old_pass = $results_array['password'];
+
+			// Generate a random password then update the database with it
+			$new_pass = '';
+			$salt = "abchefghjkmnpqrstuvwxyz0123456789";
+			srand((double)microtime()*1000000);
+			$i = 0;
+			while ($i <= 7) {
+				$num = rand() % 33;
+				$tmp = substr($salt, $num, 1);
+				$new_pass = $new_pass . $tmp;
+				$i++;
+			}
+			$database->query("UPDATE ".TABLE_PREFIX."users SET password = '".md5($new_pass)."', last_reset = '".time()."' WHERE user_id = '".$results_array['user_id']."'");
+			
+			if($database->is_error()) {
+				// Error updating database
+				$message = $database->get_error();
+			} else {
+				// Setup email to send
+				$mail_to = $email;
+				$mail_subject = $MESSAGE['SIGNUP2']['SUBJECT_LOGIN_INFO'];
+
+				// Replace placeholders from language variable with values
+				$search = array('{LOGIN_DISPLAY_NAME}', '{LOGIN_WEBSITE_TITLE}', '{LOGIN_NAME}', '{LOGIN_PASSWORD}');
+				$replace = array($results_array['display_name'], WEBSITE_TITLE, $results_array['username'], $new_pass); 
+				$mail_message = str_replace($search, $replace, $MESSAGE['SIGNUP2']['BODY_LOGIN_FORGOT']);
+
+				// Try sending the email
+				if($wb->mail(SERVER_EMAIL,$mail_to,$mail_subject,$mail_message)) { 
+					$message = $MESSAGE['FORGOT_PASS']['PASSWORD_RESET'];
+					$display_form = false;
+				} else {
+					$database->query("UPDATE ".TABLE_PREFIX."users SET password = '".$old_pass."' WHERE user_id = '".$results_array['user_id']."'");
+					$message = $MESSAGE['FORGOT_PASS']['CANNOT_EMAIL'];
+				}
+			}
+		
+		}
+
+	} else {
+		// Email doesn't exist, so tell the user
+		$message = $MESSAGE['FORGOT_PASS']['EMAIL_NOT_FOUND'];
+	}
+	
+} else {
+	$email = '';
+}
+
+if(!isset($message)) {
+	$message = $MESSAGE['FORGOT_PASS']['NO_DATA'];
+	$message_color = '000000';
+} else {
+	$message_color = 'FF0000';
+}
+	
+?>
+<h1 style="text-align: center;"><?php echo $MENU['FORGOT']; ?></h1>
+
+<form name="forgot_pass" action="<?php echo WB_URL.'/account/forgot.php'; ?>" method="post">
+	<input type="hidden" name="url" value="{URL}" />
+		<table cellpadding="5" cellspacing="0" border="0" align="center" width="500">
+		<tr>
+			<td height="40" align="center" style="color: #<?php echo $message_color; ?>;" colspan="2">
+			<?php echo $message; ?>
+			</td>
+		</tr>
+		<?php if(!isset($display_form) OR $display_form != false) { ?>
+		<tr>
+			<td height="10" colspan="2"></td>
+		</tr>
+		<tr>
+			<td width="165" height="30" align="right"><?php echo $TEXT['EMAIL']; ?>:</td>
+			<td><input type="text" maxlength="255" name="email" value="<?php echo $email; ?>" style="width: 180px;" /></td>
+			<td><input type="submit" name="submit" value="<?php echo $TEXT['SEND_DETAILS']; ?>" style="width: 180px; font-size: 10px; color: #003366; border: 1px solid #336699; background-color: #DDDDDD; padding: 3px; text-transform: uppercase;" /></td>
+		</tr>
+<!--
+		<tr>
+			<td>&nbsp;</td>
+		</tr>
+		<tr style="display: {DISPLAY_FORM}">
+			<td height="10" colspan="2"></td>
+		</tr>
+-->
+		<?php } ?>
+		</table>
 </form>
\ No newline at end of file
Index: branches/2.8.x/wb/account/preferences_form.php
===================================================================
--- branches/2.8.x/wb/account/preferences_form.php	(revision 1419)
+++ branches/2.8.x/wb/account/preferences_form.php	(revision 1420)
@@ -1,208 +1,210 @@
-<?php
-/**
- *
- * @category        frontend
- * @package         account
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-if(!defined('WB_URL')) die(header('Location: ../../index.php'));
-$ftan = $wb->getFTAN();
-?>
-
-<h2>&nbsp;<?php print $HEADING['MY_SETTINGS']; ?></h2>
-
-<form name="user" action="<?php print WB_URL.'/account/preferences.php'; ?>" method="post" style="margin-bottom: 5px;">
-<input type="hidden" name="user_id" value="{USER_ID}" />
-<?php echo $ftan; ?>
-<table cellpadding="5" cellspacing="0" border="0" width="97%">
-<tr>
-	<td width="140"><?php print $TEXT['DISPLAY_NAME']; ?>:</td>
-	<td class="value_input">
-		<input type="text" name="display_name" style="width: 380px;" maxlength="255" value="<?php print $wb->get_display_name(); ?>" />
-	</td>
-</tr>
-<tr>
-	<td><?php print $TEXT['LANGUAGE']; ?>:</td>
-	<td>
-		<select name="language" style="width: 380px;">
-		<?php
-		/**
-		 *
-		 *	Getting the languages from the database. (addons)
-		 *	It's a little bit corious, but the language-shortform is
-		 *	storred in the field "directory" ...
-		 *
-		 */
-		$query = "SELECT directory, name from ".TABLE_PREFIX."addons where type='language' order by 'name'";
-		$result = $database->query($query);
-		if ($result) {
-			$options_html = "";
-			while($data = $result->fetchRow()) {
-				$sel = ($data['directory'] == LANGUAGE) ? " selected=\"selected\" " : "";
-				$options_html .= "<option value=\"".$data['directory']."\" ".$sel.">".$data['name']." (".$data['directory'].")</option>\n";
-			}
-			echo $options_html;
-		}
-		?>
-		</select>
-	</td>
-</tr>
-<tr>
-	<td><?php print $TEXT['TIMEZONE']; ?>:</td>
-	<td>
-		<select name="timezone" style="width: 380px;">
-			<option value="-20"><?php print $TEXT['PLEASE_SELECT']; ?>...</option>
-			<?php
-				// Insert default timezone values
-				require_once(ADMIN_PATH.'/interface/timezones.php');
-				$test_time = $wb->get_timezone();
-				$options_html = "";
-				foreach($TIMEZONES as $hour_offset => $title) {
-					$sel = ($test_time == $hour_offset*60*60) ? " selected=\"selected\" " : ""; 
-					$options_html .= "<option value=\"".$hour_offset."\" ".$sel.">".$title."</option>\n";
-				}
-				print $options_html;
-?>
-
-		</select>
-	</td>
-</tr>
-<tr>
-	<td><?php print $TEXT['DATE_FORMAT']; ?>:</td>
-	<td>
-		<select name="date_format" style="width: 98%;">
-			<option value=""><?php print $TEXT['PLEASE_SELECT']; ?>...</option>
-			<?php
-			// Insert date format list
-			$user_time = true;
-			require_once(ADMIN_PATH.'/interface/date_formats.php');
-			foreach($DATE_FORMATS AS $format => $title) {
-				$format = str_replace('|', ' ', $format); // Add's white-spaces (not able to be stored in array key)
-				if($format != 'system_default') {
-					$value = $format;
-				} else {
-					$value = '';
-				}
-				if(DATE_FORMAT == $format AND !isset($_SESSION['USE_DEFAULT_DATE_FORMAT'])) {
-					$selected = ' selected="selected"';
-				} elseif($format == 'system_default' AND isset($_SESSION['USE_DEFAULT_DATE_FORMAT'])) {
-					$selected = ' selected="selected"';
-				} else {
-					$selected = '';
-				}
-				print '<option value="'.$value.'"'.$selected.'>'.$title.'</option>'."\n";
-			}
-			?>
-		</select>
-	</td>
-</tr>
-<tr>
-	<td><?php print $TEXT['TIME_FORMAT']; ?>:</td>
-	<td>
-		<select name="time_format" style="width: 98%;">
-			<option value=""><?php print $TEXT['PLEASE_SELECT']; ?>...</option>
-			<?php
-			// Insert time format list
-			$user_time = true;
-			require_once(ADMIN_PATH.'/interface/time_formats.php');
-			foreach($TIME_FORMATS AS $format => $title)
-            {
-				$format = str_replace('|', ' ', $format); // Add's white-spaces (not able to be stored in array key)
-                $value = ($format != 'system_default') ? $format : '';
-
-                $selected = ((TIME_FORMAT == $format AND ! isset($_SESSION['USE_DEFAULT_TIME_FORMAT']))
-                    OR ($format == 'system_default' AND isset($_SESSION['USE_DEFAULT_TIME_FORMAT'])))
-                	? ' selected="selected"' : '';
-
-				print '<option value="'.$value.'"'.$selected.'>'.$title.'</option>';
-			}
-			?>
-		</select>
-	</td>
-</tr>
-<tr>
-	<td>&nbsp;</td>
-	<td>
-		<input type="submit" name="submit" value="<?php print $TEXT['SAVE']; ?>" />
-		<input type="reset" name="reset" value="<?php print $TEXT['RESET']; ?>" />
-	</td>
-</tr>
-</table>
-
-</form>
-
-<h2>&nbsp;<?php print $HEADING['MY_EMAIL']; ?></h2>
-
-<form name="email" action="<?php print WB_URL.'/account/preferences.php'; ?>" method="post" style="margin-bottom: 5px;">
-<input type="hidden" name="user_id" value="{USER_ID}" />
-<?php echo $ftan; ?>
-<table cellpadding="5" cellspacing="0" border="0" width="97%">
-<tr>
-	<td width="140"><?php print $TEXT['CURRENT_PASSWORD']; ?>:</td>
-	<td>
-		<input type="password" name="current_password" style="width: 380px;" />
-	</td>
-</tr>
-<tr>
-	<td><?php print $TEXT['EMAIL']; ?>:</td>
-	<td class="value_input">
-		<input type="text" name="email" style="width: 380px;" maxlength="255" value="<?php print $wb->get_email(); ?>" />
-	</td>
-</tr>
-<tr>
-	<td>&nbsp;</td>
-	<td>
-		<input type="submit" name="submit" value="<?php print $TEXT['SAVE']; ?>" />
-		<input type="reset" name="reset" value="<?php print $TEXT['RESET']; ?>" />
-	</td>
-</tr>
-</table>
-
-</form>
-
-
-<h2>&nbsp;<?php print $HEADING['MY_PASSWORD']; ?></h2>
-
-<form name="user" action="<?php print WB_URL.'/account/preferences.php'; ?>" method="post">
-<input type="hidden" name="user_id" value="{USER_ID}" />
-<?php echo $ftan; ?>
-<table cellpadding="5" cellspacing="0" border="0" width="97%">
-<tr>
-	<td width="140"><?php print $TEXT['CURRENT_PASSWORD']; ?>:</td>
-	<td>
-		<input type="password" name="current_password" style="width: 380px;" />
-	</td>
-</tr>
-<tr>
-	<td><?php print $TEXT['NEW_PASSWORD']; ?>:</td>
-	<td>
-		<input type="password" name="new_password" style="width: 380px;" />
-	</td>
-</tr>
-<tr>
-	<td><?php print $TEXT['RETYPE_NEW_PASSWORD']; ?>:</td>
-	<td>
-		<input type="password" name="new_password2" style="width: 380px;" />
-	</td>
-</tr>
-<tr>
-	<td>&nbsp;</td>
-	<td>
-		<input type="submit" name="submit" value="<?php print $TEXT['SAVE']; ?>" />
-		<input type="reset" name="reset" value="<?php print $TEXT['RESET']; ?>" />
-	</td>
-</tr>
-</table>
-
+<?php
+/**
+ *
+ * @category        frontend
+ * @package         account
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+$ftan = $wb->getFTAN();
+?>
+
+<h2>&nbsp;<?php print $HEADING['MY_SETTINGS']; ?></h2>
+
+<form name="user" action="<?php print WB_URL.'/account/preferences.php'; ?>" method="post" style="margin-bottom: 5px;">
+<input type="hidden" name="user_id" value="{USER_ID}" />
+<?php echo $ftan; ?>
+<table cellpadding="5" cellspacing="0" border="0" width="97%">
+<tr>
+	<td width="140"><?php print $TEXT['DISPLAY_NAME']; ?>:</td>
+	<td class="value_input">
+		<input type="text" name="display_name" style="width: 380px;" maxlength="255" value="<?php print $wb->get_display_name(); ?>" />
+	</td>
+</tr>
+<tr>
+	<td><?php print $TEXT['LANGUAGE']; ?>:</td>
+	<td>
+		<select name="language" style="width: 380px;">
+		<?php
+		/**
+		 *
+		 *	Getting the languages from the database. (addons)
+		 *	It's a little bit corious, but the language-shortform is
+		 *	storred in the field "directory" ...
+		 *
+		 */
+		$query = "SELECT directory, name from ".TABLE_PREFIX."addons where type='language' order by 'name'";
+		$result = $database->query($query);
+		if ($result) {
+			$options_html = "";
+			while($data = $result->fetchRow()) {
+				$sel = ($data['directory'] == LANGUAGE) ? " selected=\"selected\" " : "";
+				$options_html .= "<option value=\"".$data['directory']."\" ".$sel.">".$data['name']." (".$data['directory'].")</option>\n";
+			}
+			echo $options_html;
+		}
+		?>
+		</select>
+	</td>
+</tr>
+<tr>
+	<td><?php print $TEXT['TIMEZONE']; ?>:</td>
+	<td>
+		<select name="timezone" style="width: 380px;">
+			<option value="-20"><?php print $TEXT['PLEASE_SELECT']; ?>...</option>
+			<?php
+				// Insert default timezone values
+				require_once(ADMIN_PATH.'/interface/timezones.php');
+				$test_time = $wb->get_timezone();
+				$options_html = "";
+				foreach($TIMEZONES as $hour_offset => $title) {
+					$sel = ($test_time == $hour_offset*60*60) ? " selected=\"selected\" " : ""; 
+					$options_html .= "<option value=\"".$hour_offset."\" ".$sel.">".$title."</option>\n";
+				}
+				print $options_html;
+?>
+
+		</select>
+	</td>
+</tr>
+<tr>
+	<td><?php print $TEXT['DATE_FORMAT']; ?>:</td>
+	<td>
+		<select name="date_format" style="width: 98%;">
+			<option value=""><?php print $TEXT['PLEASE_SELECT']; ?>...</option>
+			<?php
+			// Insert date format list
+			$user_time = true;
+			require_once(ADMIN_PATH.'/interface/date_formats.php');
+			foreach($DATE_FORMATS AS $format => $title) {
+				$format = str_replace('|', ' ', $format); // Add's white-spaces (not able to be stored in array key)
+				if($format != 'system_default') {
+					$value = $format;
+				} else {
+					$value = '';
+				}
+				if(DATE_FORMAT == $format AND !isset($_SESSION['USE_DEFAULT_DATE_FORMAT'])) {
+					$selected = ' selected="selected"';
+				} elseif($format == 'system_default' AND isset($_SESSION['USE_DEFAULT_DATE_FORMAT'])) {
+					$selected = ' selected="selected"';
+				} else {
+					$selected = '';
+				}
+				print '<option value="'.$value.'"'.$selected.'>'.$title.'</option>'."\n";
+			}
+			?>
+		</select>
+	</td>
+</tr>
+<tr>
+	<td><?php print $TEXT['TIME_FORMAT']; ?>:</td>
+	<td>
+		<select name="time_format" style="width: 98%;">
+			<option value=""><?php print $TEXT['PLEASE_SELECT']; ?>...</option>
+			<?php
+			// Insert time format list
+			$user_time = true;
+			require_once(ADMIN_PATH.'/interface/time_formats.php');
+			foreach($TIME_FORMATS AS $format => $title)
+            {
+				$format = str_replace('|', ' ', $format); // Add's white-spaces (not able to be stored in array key)
+                $value = ($format != 'system_default') ? $format : '';
+
+                $selected = ((TIME_FORMAT == $format AND ! isset($_SESSION['USE_DEFAULT_TIME_FORMAT']))
+                    OR ($format == 'system_default' AND isset($_SESSION['USE_DEFAULT_TIME_FORMAT'])))
+                	? ' selected="selected"' : '';
+
+				print '<option value="'.$value.'"'.$selected.'>'.$title.'</option>';
+			}
+			?>
+		</select>
+	</td>
+</tr>
+<tr>
+	<td>&nbsp;</td>
+	<td>
+		<input type="submit" name="submit" value="<?php print $TEXT['SAVE']; ?>" />
+		<input type="reset" name="reset" value="<?php print $TEXT['RESET']; ?>" />
+	</td>
+</tr>
+</table>
+
+</form>
+
+<h2>&nbsp;<?php print $HEADING['MY_EMAIL']; ?></h2>
+
+<form name="email" action="<?php print WB_URL.'/account/preferences.php'; ?>" method="post" style="margin-bottom: 5px;">
+<input type="hidden" name="user_id" value="{USER_ID}" />
+<?php echo $ftan; ?>
+<table cellpadding="5" cellspacing="0" border="0" width="97%">
+<tr>
+	<td width="140"><?php print $TEXT['CURRENT_PASSWORD']; ?>:</td>
+	<td>
+		<input type="password" name="current_password" style="width: 380px;" />
+	</td>
+</tr>
+<tr>
+	<td><?php print $TEXT['EMAIL']; ?>:</td>
+	<td class="value_input">
+		<input type="text" name="email" style="width: 380px;" maxlength="255" value="<?php print $wb->get_email(); ?>" />
+	</td>
+</tr>
+<tr>
+	<td>&nbsp;</td>
+	<td>
+		<input type="submit" name="submit" value="<?php print $TEXT['SAVE']; ?>" />
+		<input type="reset" name="reset" value="<?php print $TEXT['RESET']; ?>" />
+	</td>
+</tr>
+</table>
+
+</form>
+
+
+<h2>&nbsp;<?php print $HEADING['MY_PASSWORD']; ?></h2>
+
+<form name="user" action="<?php print WB_URL.'/account/preferences.php'; ?>" method="post">
+<input type="hidden" name="user_id" value="{USER_ID}" />
+<?php echo $ftan; ?>
+<table cellpadding="5" cellspacing="0" border="0" width="97%">
+<tr>
+	<td width="140"><?php print $TEXT['CURRENT_PASSWORD']; ?>:</td>
+	<td>
+		<input type="password" name="current_password" style="width: 380px;" />
+	</td>
+</tr>
+<tr>
+	<td><?php print $TEXT['NEW_PASSWORD']; ?>:</td>
+	<td>
+		<input type="password" name="new_password" style="width: 380px;" />
+	</td>
+</tr>
+<tr>
+	<td><?php print $TEXT['RETYPE_NEW_PASSWORD']; ?>:</td>
+	<td>
+		<input type="password" name="new_password2" style="width: 380px;" />
+	</td>
+</tr>
+<tr>
+	<td>&nbsp;</td>
+	<td>
+		<input type="submit" name="submit" value="<?php print $TEXT['SAVE']; ?>" />
+		<input type="reset" name="reset" value="<?php print $TEXT['RESET']; ?>" />
+	</td>
+</tr>
+</table>
+
 </form>
\ No newline at end of file
Index: branches/2.8.x/wb/account/details.php
===================================================================
--- branches/2.8.x/wb/account/details.php	(revision 1419)
+++ branches/2.8.x/wb/account/details.php	(revision 1420)
@@ -16,10 +16,8 @@
  *
  */
 
-if(!defined('WB_URL')) {
-	header('Location: ../pages/index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 // Get and sanitize entered values
 $display_name = $wb->add_slashes(strip_tags($wb->get_post('display_name')));
Index: branches/2.8.x/wb/account/email.php
===================================================================
--- branches/2.8.x/wb/account/email.php	(revision 1419)
+++ branches/2.8.x/wb/account/email.php	(revision 1420)
@@ -16,10 +16,8 @@
  *
  */
 
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 // Get the values entered
 $current_password = $wb->get_post('current_password');
Index: branches/2.8.x/wb/account/signup2.php
===================================================================
--- branches/2.8.x/wb/account/signup2.php	(revision 1419)
+++ branches/2.8.x/wb/account/signup2.php	(revision 1420)
@@ -16,10 +16,8 @@
  *
  */
 
-if(!defined('WB_URL')) {
-	header('Location: ../pages/index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 require_once(WB_PATH.'/framework/class.wb.php');
 $wb = new wb('Start', 'start', false, false);
Index: branches/2.8.x/wb/account/signup_form.php
===================================================================
--- branches/2.8.x/wb/account/signup_form.php	(revision 1419)
+++ branches/2.8.x/wb/account/signup_form.php	(revision 1420)
@@ -1,90 +1,89 @@
-<?php
-/**
- *
- * @category        frontend
- * @package         account
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
-require_once(WB_PATH.'/include/captcha/captcha.php');
-
-?>
-
-<h1>&nbsp;<?php echo $TEXT['SIGNUP']; ?></h1>
-
-<form name="user" action="<?php echo WB_URL.'/account/signup.php'; ?>" method="post">
-	<?php echo $admin->getFTAN(); ?>
-	<?php if(ENABLED_ASP) { // add some honeypot-fields
-	?>
-    <div style="display:none;">
-	<input type="hidden" name="submitted_when" value="<?php $t=time(); echo $t; $_SESSION['submitted_when']=$t; ?>" />
-	<p class="nixhier">
-	email-address:
-	<label for="email-address">Leave this field email-address blank:</label>
-	<input id="email-address" name="email-address" size="60" value="" /><br />
-	username (id):
-	<label for="name">Leave this field name blank:</label>
-	<input id="name" name="name" size="60" value="" /><br />
-	Full Name:
-	<label for="full_name">Leave this field full_name blank:</label>
-	<input id="full_name" name="full_name" size="60" value="" /><br />
-	</p>
-	<?php }
-	?>
-    </div>
-<table cellpadding="5" cellspacing="0" border="0" width="90%">
-<tr>
-	<td width="180"><?php echo $TEXT['USERNAME']; ?>:</td>
-	<td class="value_input">
-		<input type="text" name="username" maxlength="30" style="width:300px;"/>
-	</td>
-</tr>
-<tr>
-	<td><?php echo $TEXT['DISPLAY_NAME']; ?> (<?php echo $TEXT['FULL_NAME']; ?>):</td>
-	<td class="value_input">
-		<input type="text" name="display_name" maxlength="255" style="width:300px;" />
-	</td>
-</tr>
-<tr>
-	<td><?php echo $TEXT['EMAIL']; ?>:</td>
-	<td class="value_input">
-		<input type="text" name="email" maxlength="255" style="width:300px;"/>
-	</td>
-</tr>
-<?php
-// Captcha
-if(ENABLED_CAPTCHA) {
-	?><tr>
-		<td class="field_title"><?php echo $TEXT['VERIFICATION']; ?>:</td>
-		<td><?php call_captcha(); ?></td>
-		</tr>
-	<?php
-}
-?>
-<tr>
-	<td>&nbsp;</td>
-	<td>
-		<input type="submit" name="submit" value="<?php echo $TEXT['SIGNUP']; ?>" />
-		<input type="reset" name="reset" value="<?php echo $TEXT['RESET']; ?>" />
-	</td>
-</tr>
-</table>
-
-</form>
-
-<br />
-&nbsp; 
+<?php
+/**
+ *
+ * @category        frontend
+ * @package         account
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+require_once(WB_PATH.'/include/captcha/captcha.php');
+
+?>
+
+<h1>&nbsp;<?php echo $TEXT['SIGNUP']; ?></h1>
+
+<form name="user" action="<?php echo WB_URL.'/account/signup.php'; ?>" method="post">
+	<?php echo $admin->getFTAN(); ?>
+	<?php if(ENABLED_ASP) { // add some honeypot-fields
+	?>
+    <div style="display:none;">
+	<input type="hidden" name="submitted_when" value="<?php $t=time(); echo $t; $_SESSION['submitted_when']=$t; ?>" />
+	<p class="nixhier">
+	email-address:
+	<label for="email-address">Leave this field email-address blank:</label>
+	<input id="email-address" name="email-address" size="60" value="" /><br />
+	username (id):
+	<label for="name">Leave this field name blank:</label>
+	<input id="name" name="name" size="60" value="" /><br />
+	Full Name:
+	<label for="full_name">Leave this field full_name blank:</label>
+	<input id="full_name" name="full_name" size="60" value="" /><br />
+	</p>
+	<?php }
+	?>
+    </div>
+<table cellpadding="5" cellspacing="0" border="0" width="90%">
+<tr>
+	<td width="180"><?php echo $TEXT['USERNAME']; ?>:</td>
+	<td class="value_input">
+		<input type="text" name="username" maxlength="30" style="width:300px;"/>
+	</td>
+</tr>
+<tr>
+	<td><?php echo $TEXT['DISPLAY_NAME']; ?> (<?php echo $TEXT['FULL_NAME']; ?>):</td>
+	<td class="value_input">
+		<input type="text" name="display_name" maxlength="255" style="width:300px;" />
+	</td>
+</tr>
+<tr>
+	<td><?php echo $TEXT['EMAIL']; ?>:</td>
+	<td class="value_input">
+		<input type="text" name="email" maxlength="255" style="width:300px;"/>
+	</td>
+</tr>
+<?php
+// Captcha
+if(ENABLED_CAPTCHA) {
+	?><tr>
+		<td class="field_title"><?php echo $TEXT['VERIFICATION']; ?>:</td>
+		<td><?php call_captcha(); ?></td>
+		</tr>
+	<?php
+}
+?>
+<tr>
+	<td>&nbsp;</td>
+	<td>
+		<input type="submit" name="submit" value="<?php echo $TEXT['SIGNUP']; ?>" />
+		<input type="reset" name="reset" value="<?php echo $TEXT['RESET']; ?>" />
+	</td>
+</tr>
+</table>
+
+</form>
+
+<br />
+&nbsp; 
Index: branches/2.8.x/wb/framework/class.admin.php
===================================================================
--- branches/2.8.x/wb/framework/class.admin.php	(revision 1419)
+++ branches/2.8.x/wb/framework/class.admin.php	(revision 1420)
@@ -16,10 +16,8 @@
  *
  */
 
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 require_once(WB_PATH.'/framework/class.wb.php');
 
Index: branches/2.8.x/wb/framework/functions-utf8.php
===================================================================
--- branches/2.8.x/wb/framework/functions-utf8.php	(revision 1419)
+++ branches/2.8.x/wb/framework/functions-utf8.php	(revision 1420)
@@ -43,10 +43,8 @@
 //   entities_to_umlauts2()
 //   umlauts_to_entities2()
 
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 /*
  * check for mb_string support
Index: branches/2.8.x/wb/framework/module.functions.php
===================================================================
--- branches/2.8.x/wb/framework/module.functions.php	(revision 1419)
+++ branches/2.8.x/wb/framework/module.functions.php	(revision 1420)
@@ -31,8 +31,8 @@
 	NOTE: Some functions were added for module developers to make the creation of own module easier
 */
 
-// prevent this file from being accessed directly
-if(!defined('WB_PATH')) die(header('Location: index.php'));  
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 /*
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Index: branches/2.8.x/wb/framework/initialize.php
===================================================================
--- branches/2.8.x/wb/framework/initialize.php	(revision 1419)
+++ branches/2.8.x/wb/framework/initialize.php	(revision 1420)
@@ -16,6 +16,8 @@
  *
  */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 //set_include_path(get_include_path() . PATH_SEPARATOR . WB_PATH);
 
 if (file_exists(WB_PATH.'/framework/class.database.php')) {
Index: branches/2.8.x/wb/framework/class.wbmailer.php
===================================================================
--- branches/2.8.x/wb/framework/class.wbmailer.php	(revision 1419)
+++ branches/2.8.x/wb/framework/class.wbmailer.php	(revision 1420)
@@ -23,14 +23,9 @@
 
 */
 
-/*
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
-wbmailer class
-
-This class is a subclass of the PHPMailer class and replaces the mail() function of PHP
-
-*/
-
 // Include PHPMailer class
 require_once(WB_PATH."/include/phpmailer/class.phpmailer.php");
 
Index: branches/2.8.x/wb/framework/class.database.php
===================================================================
--- branches/2.8.x/wb/framework/class.database.php	(revision 1419)
+++ branches/2.8.x/wb/framework/class.database.php	(revision 1420)
@@ -25,11 +25,8 @@
 
 */
 
-// Stop this file from being accessed directly
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 if(!defined('DB_URL')) {
 	//define('DB_URL', DB_TYPE.'://'.DB_USERNAME.':'.DB_PASSWORD.'@'.DB_HOST.'/'.DB_NAME);
Index: branches/2.8.x/wb/framework/functions.php
===================================================================
--- branches/2.8.x/wb/framework/functions.php	(revision 1419)
+++ branches/2.8.x/wb/framework/functions.php	(revision 1420)
@@ -16,11 +16,8 @@
  *
 */
 
-// Stop this file from being accessed directly
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit;
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 // Define that this file has been loaded
 define('FUNCTIONS_FILE_LOADED', true);
Index: branches/2.8.x/wb/framework/class.login.php
===================================================================
--- branches/2.8.x/wb/framework/class.login.php	(revision 1419)
+++ branches/2.8.x/wb/framework/class.login.php	(revision 1420)
@@ -16,11 +16,8 @@
  *
  */
 
-// Stop this file from being accessed directly
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 define('LOGIN_CLASS_LOADED', true);
 
Index: branches/2.8.x/wb/framework/class.wb.php
===================================================================
--- branches/2.8.x/wb/framework/class.wb.php	(revision 1419)
+++ branches/2.8.x/wb/framework/class.wb.php	(revision 1420)
@@ -16,6 +16,8 @@
  *
  */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 // Include PHPLIB template class
 require_once(WB_PATH."/include/phplib/template.inc");
 
Index: branches/2.8.x/wb/framework/class.order.php
===================================================================
--- branches/2.8.x/wb/framework/class.order.php	(revision 1419)
+++ branches/2.8.x/wb/framework/class.order.php	(revision 1420)
@@ -32,11 +32,8 @@
 
 */
 
-// Stop this file from being accessed directly
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 define('ORDERING_CLASS_LOADED', true);
 
Index: branches/2.8.x/wb/framework/addon.precheck.inc.php
===================================================================
--- branches/2.8.x/wb/framework/addon.precheck.inc.php	(revision 1419)
+++ branches/2.8.x/wb/framework/addon.precheck.inc.php	(revision 1420)
@@ -1,331 +1,331 @@
-<?php
-/**
- *
- * @category        module
- * @package         precheck
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// prevent this file from being accessed directly
-if (!defined('WB_PATH')) die(header('Location: ../index.php'));
-
-function getVersion($version, $strip_suffix = true)
-{
-	/**
-	 * This funtion creates a version string following the major.minor.revision convention
-	 * The minor and revision part of the version may not exceed 999 (three digits)
-	 * An optional suffix part can be added after revision (requires $strip_suffix = false)
-	 *
-	 * EXAMPLES: input --> output
-	 *	5 --> 5.000000; 5.0 --> 5.000000; 5.0.0 --> 5.000000
-	 * 	5.2 --> 5.002000; 5.20 --> 5.002000; 5.2.0 --> 5.002000
-	 * 	5.21 --> 5.002001; 5.2.1 --> 5.002001;
-	 * 	5.27.1 --> 5.027001; 5.2.71 --> 5.002071;
-	 * 	5.27.1 rc1 --> 5.027001_RC1 ($strip_suffix:= false)
-	 */
-	// replace comma by decimal point
-	$version = str_replace(',', '.', $version);
-
-	// convert version into major.minor.revision numbering system
-	list($major, $minor, $revision) = explode('.', $version, 3);
-
-	// convert versioning style 5.21 into 5.2.1
-	if ($revision == '' && strlen(intval($minor)) == 2) {
-		$revision = substr($minor, -1);
-		$minor = substr($minor, 0, 1);
-	}
-	
-	// extract possible non numerical suffix from revision part (e.g. Alpha, Beta, RC1)
-	$suffix = strtoupper(trim(substr($revision, strlen(intval($revision)))));
-
-/*
-	return (int)$major . '.' . sprintf('%03d', (int)$minor) . sprintf('%03d', (int)$revision) .
-		(($strip_suffix == false && $suffix != '') ? '_' . $suffix : '');
-*/
-	// return standard version number (minor and revision numbers may not exceed 999)
-    return sprintf('%d.%03d.%03d%s', (int)$major, (int)minor, (int)$revision,
-    (($strip_suffix == false && $suffix != '') ? '_' . $suffix : ''));
-}
-
-/**
- *	As "version_compare" it self seems only got trouble 
- *	within words like "Alpha", "Beta" a.s.o. this function
- *	only modify the version-string in the way that these words are replaced by values/numbers.
- *
- *	E.g:	"1.2.3 Beta2" => "1.2.322"
- *			"0.1.1 ALPHA" => "0.1.11"
- *
- *	Notice:	Please keep in mind, that this will not correct the way "version_control" 
- *			handel "1 < 1.0 < 1.0.0 < 1.0.0.0" and will not correct missformed version-strings
- *			below 2.7, e.g. "1.002 released candidate 2.3"
- *			
- *	@since	2.8.0 RC2
- *
- *	@param	string	A versionstring
- *	@return	string	The modificated versionstring
- *
- */
-function getVersion2 ($version="") {
-	
-	$states = array (
-		'1' => "alpha",
-		'2' => "beta",
-		'4' => "rc",
-		'8' => "final"	
-	);
-
-	$version = strtolower($version);
-	
-	foreach($states as $value=>$keys) $version = str_replace($keys, $value, $version);
-
-	$version = str_replace(" ", "", $version);
-
-	return $version;
-}
-
-function versionCompare($version1, $version2, $operator = '>=')
-{
-	/**
-	 * This funtion performs a comparison of two provided version strings
-	 * The versions are first converted into a string following the major.minor.revision 
-	 * convention and performs a version_compare afterwards.
-	 */
-	// return version_compare(getVersion($version1), getVersion($version2), $operator);
-	return version_compare(getVersion2($version1), getVersion2($version2), $operator);
-}
-
-function sortPreCheckArray($precheck_array)
-{
-	/**
-	 * This funtion sorts the precheck array to a common format
-	 */
-	// define desired precheck order
-	$key_order = array('WB_VERSION', 'WB_ADDONS', 'PHP_VERSION', 'PHP_EXTENSIONS', 'PHP_SETTINGS', 'CUSTOM_CHECKS');
-
-	$temp_array = array();
-	foreach($key_order as $key) {
-		if (!isset($precheck_array[$key])) continue;
-		$temp_array[$key] = $precheck_array[$key];
-	}
-	return $temp_array;
-}
-
-function preCheckAddon($temp_addon_file)
-{
-	/**
-	 * This funtion performs pretest upfront of the Add-On installation process.
-	 * The requirements can be specified via the array $PRECHECK which needs to
-	 * be defined in the optional Add-on file precheck.php.
-	 */
-	global $database, $admin, $TEXT, $HEADING, $MESSAGE;
-	
-	// path to the temporary Add-on folder
-	$temp_path = WB_PATH . '/temp/unzip';
-	
-	// check if file precheck.php exists for the Add-On uploaded via WB installation routine
-	if (!file_exists($temp_path . '/precheck.php')) return;
-	
-	// unset any previous declared PRECHECK array
-	unset($PRECHECK);
-
-	// include Add-On precheck.php file
-	include($temp_path . '/precheck.php');
-	
-	// check if there are any Add-On requirements to check for
-	if (!(isset($PRECHECK) && count($PRECHECK) > 0)) return;
-	
-	// sort precheck array
-	$PRECHECK = sortPreCheckArray($PRECHECK);
-	
-	$failed_checks = 0;
-	$msg = array();
-	// check if specified addon requirements are fullfilled
-	foreach ($PRECHECK as $key => $value) {
-		switch ($key) {
-			case 'WB_VERSION':
-				if (isset($value['VERSION'])) {
-					// obtain operator for string comparison if exist
-					$operator = (isset($value['OPERATOR']) &&  trim($value['OPERATOR']) != '') ? $value['OPERATOR'] : '>=';
-				
-					// compare versions and extract actual status
-					$status = versionCompare(WB_VERSION, $value['VERSION'], $operator);
-					$msg[] = array(
-						'check'		=> 'WB-' . $TEXT['VERSION'] .': ',
-						'required'	=> htmlentities($operator) . $value['VERSION'],
-						'actual'	=> WB_VERSION,
-						'status'	=> $status
-					);
-
-					// increase counter if required
-					if (!$status) $failed_checks++;
-				}
-				break;
-
-			case 'WB_ADDONS':
-				if (is_array($PRECHECK['WB_ADDONS'])) {
-					foreach($PRECHECK['WB_ADDONS'] as $addon => $values) {
-						if (is_array($values)) {
-							// extract module version and operator
-							$version = (isset($values['VERSION']) &&  trim($values['VERSION']) != '') ? $values['VERSION'] : '';
-							$operator = (isset($values['OPERATOR']) &&  trim($values['OPERATOR']) != '') ? $values['OPERATOR'] : '>=';
-						} else {
-							// no version and operator specified (only check if addon exists)
-							$addon = strip_tags($values);
-							$version = ''; $operator = '';
-						}
-					
-						// check if addon is listed in WB database
-						$table = TABLE_PREFIX . 'addons';
-						$sql = "SELECT * FROM `$table` WHERE `directory` = '" . addslashes($addon) . "'";
-						$results = $database->query($sql);
-					
-						$status = false; $addon_status = $TEXT['NOT_INSTALLED'];
-						if ($results && $row = $results->fetchRow()) {
-							$status = true; 
-							$addon_status = $TEXT['INSTALLED'];
-						
-							// compare version if required
-							if ($version != '') {
-								$status = versionCompare($row['version'], $version, $operator);
-								$addon_status = $row['version'];
-							}
-						}
-					
-						// provide addon status
-						$msg[] = array(
-							'check'		=> '&nbsp; ' . $TEXT['ADDON'] . ': ' . htmlentities($addon),
-							'required'	=> ($version != '') ? $operator . '&nbsp;' . $version : $TEXT['INSTALLED'],
-							'actual'	=> $addon_status,
-							'status'	=> $status
-						);
-						
-						// increase counter if required
-						if (!$status) $failed_checks++;
-					}
-				}
-				break;
-
-			case 'PHP_VERSION':
-				if (isset($value['VERSION'])) {
-					// obtain operator for string comparison if exist
-					$operator = (isset($value['OPERATOR']) &&  trim($value['OPERATOR']) != '') ? $value['OPERATOR'] : '>=';
-				
-					// compare versions and extract actual status
-					$status = versionCompare(PHP_VERSION, $value['VERSION'], $operator);
-					$msg[] = array(
-						'check'		=> 'PHP-' . $TEXT['VERSION'] .': ',
-						'required'	=> htmlentities($operator) . '&nbsp;' . $value['VERSION'],
-						'actual'	=> PHP_VERSION,
-						'status'	=> $status
-					);
-
-					// increase counter if required
-					if (!$status) $failed_checks++;
-
-				}
-				break;
-
-			case 'PHP_EXTENSIONS':
-				if (is_array($PRECHECK['PHP_EXTENSIONS'])) {
-					foreach($PRECHECK['PHP_EXTENSIONS'] as $extension) {
-						$status = extension_loaded(strtolower($extension));
-						$msg[] = array(
-							'check'		=> '&nbsp; ' . $TEXT['EXTENSION'] . ': ' . htmlentities($extension),
-							'required'	=> $TEXT['INSTALLED'],
-							'actual'	=> ($status) ? $TEXT['INSTALLED'] : $TEXT['NOT_INSTALLED'],
-							'status'	=> $status
-						);
-
-						// increase counter if required
-						if (!$status) $failed_checks++;
-					}
-				}
-				break;
-
-			case 'PHP_SETTINGS':
-				if (is_array($PRECHECK['PHP_SETTINGS'])) {
-					foreach($PRECHECK['PHP_SETTINGS'] as $setting => $value) {
-						$actual_setting = ($temp = ini_get($setting)) ? $temp : 0;
-						$status = ($actual_setting == $value);
-					
-						$msg[] = array(
-							'check'		=> '&nbsp; '. ($setting),
-							'required'	=> $value,
-							'actual'	=> $actual_setting,
-							'status'	=> $status
-						);
-
-						// increase counter if required
-						if (!$status) $failed_checks++;
-					}
-				}
-				break;
-
-			case 'CUSTOM_CHECKS':
-				if (is_array($PRECHECK['CUSTOM_CHECKS'])) {
-					foreach($PRECHECK['CUSTOM_CHECKS'] as $key => $values) {
-						$status = (true === array_key_exists('STATUS', $values )) ? $values['STATUS'] : false;
-						$msg[] = array(
-							'check'		=> $key,
-							'required'	=> $values['REQUIRED'],
-							'actual'	=> $values['ACTUAL'],
-							'status'	=> $status
-						);
-					}
-
-					// increase counter if required
-					if (!$status) $failed_checks++;
-				}
-				break;
-		}
-	}
-
-	// leave if all requirements are fullfilled
-	if ($failed_checks == 0) return;
-	
-	// output summary table with requirements not fullfilled
-	echo <<< EOT
-	<h2>{$HEADING['ADDON_PRECHECK_FAILED']}</h2>
-	<p>{$MESSAGE['ADDON']['PRECHECK_FAILED']}</p> 
-
-	<table width="700px" cellpadding="4" border="0" style="margin: 0.5em; border-collapse: collapse; border: 1px solid silver;">
-	<tr>
-		<th>{$TEXT['REQUIREMENT']}:</th>
-		<th>{$TEXT['REQUIRED']}:</th>
-		<th>{$TEXT['CURRENT']}:</th>
-	</tr>
-EOT;
-
-	foreach($msg as $check) {
-		echo '<tr>';
-		$style = $check['status'] ? 'color: #46882B;' : 'color: #C00;';
-		foreach($check as $key => $value) {
-			if ($key == 'status') continue;
-			
-			echo '<td style="' . $style . '">' . $value . '</td>';
-		}
-		echo '</tr>';
-	}
-	echo '</table>';
-
-	// delete the temp unzip directory
-	rm_full_dir($temp_path);	
-
-	// delete the temporary zip file of the Add-on
-	if(file_exists($temp_addon_file)) { unlink($temp_addon_file); }	
-	
-	// output status message and die
-	$admin->print_error('');
-}
-
+<?php
+/**
+ *
+ * @category        module
+ * @package         precheck
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+function getVersion($version, $strip_suffix = true)
+{
+	/**
+	 * This funtion creates a version string following the major.minor.revision convention
+	 * The minor and revision part of the version may not exceed 999 (three digits)
+	 * An optional suffix part can be added after revision (requires $strip_suffix = false)
+	 *
+	 * EXAMPLES: input --> output
+	 *	5 --> 5.000000; 5.0 --> 5.000000; 5.0.0 --> 5.000000
+	 * 	5.2 --> 5.002000; 5.20 --> 5.002000; 5.2.0 --> 5.002000
+	 * 	5.21 --> 5.002001; 5.2.1 --> 5.002001;
+	 * 	5.27.1 --> 5.027001; 5.2.71 --> 5.002071;
+	 * 	5.27.1 rc1 --> 5.027001_RC1 ($strip_suffix:= false)
+	 */
+	// replace comma by decimal point
+	$version = str_replace(',', '.', $version);
+
+	// convert version into major.minor.revision numbering system
+	list($major, $minor, $revision) = explode('.', $version, 3);
+
+	// convert versioning style 5.21 into 5.2.1
+	if ($revision == '' && strlen(intval($minor)) == 2) {
+		$revision = substr($minor, -1);
+		$minor = substr($minor, 0, 1);
+	}
+	
+	// extract possible non numerical suffix from revision part (e.g. Alpha, Beta, RC1)
+	$suffix = strtoupper(trim(substr($revision, strlen(intval($revision)))));
+
+/*
+	return (int)$major . '.' . sprintf('%03d', (int)$minor) . sprintf('%03d', (int)$revision) .
+		(($strip_suffix == false && $suffix != '') ? '_' . $suffix : '');
+*/
+	// return standard version number (minor and revision numbers may not exceed 999)
+    return sprintf('%d.%03d.%03d%s', (int)$major, (int)minor, (int)$revision,
+    (($strip_suffix == false && $suffix != '') ? '_' . $suffix : ''));
+}
+
+/**
+ *	As "version_compare" it self seems only got trouble 
+ *	within words like "Alpha", "Beta" a.s.o. this function
+ *	only modify the version-string in the way that these words are replaced by values/numbers.
+ *
+ *	E.g:	"1.2.3 Beta2" => "1.2.322"
+ *			"0.1.1 ALPHA" => "0.1.11"
+ *
+ *	Notice:	Please keep in mind, that this will not correct the way "version_control" 
+ *			handel "1 < 1.0 < 1.0.0 < 1.0.0.0" and will not correct missformed version-strings
+ *			below 2.7, e.g. "1.002 released candidate 2.3"
+ *			
+ *	@since	2.8.0 RC2
+ *
+ *	@param	string	A versionstring
+ *	@return	string	The modificated versionstring
+ *
+ */
+function getVersion2 ($version="") {
+	
+	$states = array (
+		'1' => "alpha",
+		'2' => "beta",
+		'4' => "rc",
+		'8' => "final"	
+	);
+
+	$version = strtolower($version);
+	
+	foreach($states as $value=>$keys) $version = str_replace($keys, $value, $version);
+
+	$version = str_replace(" ", "", $version);
+
+	return $version;
+}
+
+function versionCompare($version1, $version2, $operator = '>=')
+{
+	/**
+	 * This funtion performs a comparison of two provided version strings
+	 * The versions are first converted into a string following the major.minor.revision 
+	 * convention and performs a version_compare afterwards.
+	 */
+	// return version_compare(getVersion($version1), getVersion($version2), $operator);
+	return version_compare(getVersion2($version1), getVersion2($version2), $operator);
+}
+
+function sortPreCheckArray($precheck_array)
+{
+	/**
+	 * This funtion sorts the precheck array to a common format
+	 */
+	// define desired precheck order
+	$key_order = array('WB_VERSION', 'WB_ADDONS', 'PHP_VERSION', 'PHP_EXTENSIONS', 'PHP_SETTINGS', 'CUSTOM_CHECKS');
+
+	$temp_array = array();
+	foreach($key_order as $key) {
+		if (!isset($precheck_array[$key])) continue;
+		$temp_array[$key] = $precheck_array[$key];
+	}
+	return $temp_array;
+}
+
+function preCheckAddon($temp_addon_file)
+{
+	/**
+	 * This funtion performs pretest upfront of the Add-On installation process.
+	 * The requirements can be specified via the array $PRECHECK which needs to
+	 * be defined in the optional Add-on file precheck.php.
+	 */
+	global $database, $admin, $TEXT, $HEADING, $MESSAGE;
+	
+	// path to the temporary Add-on folder
+	$temp_path = WB_PATH . '/temp/unzip';
+	
+	// check if file precheck.php exists for the Add-On uploaded via WB installation routine
+	if (!file_exists($temp_path . '/precheck.php')) return;
+	
+	// unset any previous declared PRECHECK array
+	unset($PRECHECK);
+
+	// include Add-On precheck.php file
+	include($temp_path . '/precheck.php');
+	
+	// check if there are any Add-On requirements to check for
+	if (!(isset($PRECHECK) && count($PRECHECK) > 0)) return;
+	
+	// sort precheck array
+	$PRECHECK = sortPreCheckArray($PRECHECK);
+	
+	$failed_checks = 0;
+	$msg = array();
+	// check if specified addon requirements are fullfilled
+	foreach ($PRECHECK as $key => $value) {
+		switch ($key) {
+			case 'WB_VERSION':
+				if (isset($value['VERSION'])) {
+					// obtain operator for string comparison if exist
+					$operator = (isset($value['OPERATOR']) &&  trim($value['OPERATOR']) != '') ? $value['OPERATOR'] : '>=';
+				
+					// compare versions and extract actual status
+					$status = versionCompare(WB_VERSION, $value['VERSION'], $operator);
+					$msg[] = array(
+						'check'		=> 'WB-' . $TEXT['VERSION'] .': ',
+						'required'	=> htmlentities($operator) . $value['VERSION'],
+						'actual'	=> WB_VERSION,
+						'status'	=> $status
+					);
+
+					// increase counter if required
+					if (!$status) $failed_checks++;
+				}
+				break;
+
+			case 'WB_ADDONS':
+				if (is_array($PRECHECK['WB_ADDONS'])) {
+					foreach($PRECHECK['WB_ADDONS'] as $addon => $values) {
+						if (is_array($values)) {
+							// extract module version and operator
+							$version = (isset($values['VERSION']) &&  trim($values['VERSION']) != '') ? $values['VERSION'] : '';
+							$operator = (isset($values['OPERATOR']) &&  trim($values['OPERATOR']) != '') ? $values['OPERATOR'] : '>=';
+						} else {
+							// no version and operator specified (only check if addon exists)
+							$addon = strip_tags($values);
+							$version = ''; $operator = '';
+						}
+					
+						// check if addon is listed in WB database
+						$table = TABLE_PREFIX . 'addons';
+						$sql = "SELECT * FROM `$table` WHERE `directory` = '" . addslashes($addon) . "'";
+						$results = $database->query($sql);
+					
+						$status = false; $addon_status = $TEXT['NOT_INSTALLED'];
+						if ($results && $row = $results->fetchRow()) {
+							$status = true; 
+							$addon_status = $TEXT['INSTALLED'];
+						
+							// compare version if required
+							if ($version != '') {
+								$status = versionCompare($row['version'], $version, $operator);
+								$addon_status = $row['version'];
+							}
+						}
+					
+						// provide addon status
+						$msg[] = array(
+							'check'		=> '&nbsp; ' . $TEXT['ADDON'] . ': ' . htmlentities($addon),
+							'required'	=> ($version != '') ? $operator . '&nbsp;' . $version : $TEXT['INSTALLED'],
+							'actual'	=> $addon_status,
+							'status'	=> $status
+						);
+						
+						// increase counter if required
+						if (!$status) $failed_checks++;
+					}
+				}
+				break;
+
+			case 'PHP_VERSION':
+				if (isset($value['VERSION'])) {
+					// obtain operator for string comparison if exist
+					$operator = (isset($value['OPERATOR']) &&  trim($value['OPERATOR']) != '') ? $value['OPERATOR'] : '>=';
+				
+					// compare versions and extract actual status
+					$status = versionCompare(PHP_VERSION, $value['VERSION'], $operator);
+					$msg[] = array(
+						'check'		=> 'PHP-' . $TEXT['VERSION'] .': ',
+						'required'	=> htmlentities($operator) . '&nbsp;' . $value['VERSION'],
+						'actual'	=> PHP_VERSION,
+						'status'	=> $status
+					);
+
+					// increase counter if required
+					if (!$status) $failed_checks++;
+
+				}
+				break;
+
+			case 'PHP_EXTENSIONS':
+				if (is_array($PRECHECK['PHP_EXTENSIONS'])) {
+					foreach($PRECHECK['PHP_EXTENSIONS'] as $extension) {
+						$status = extension_loaded(strtolower($extension));
+						$msg[] = array(
+							'check'		=> '&nbsp; ' . $TEXT['EXTENSION'] . ': ' . htmlentities($extension),
+							'required'	=> $TEXT['INSTALLED'],
+							'actual'	=> ($status) ? $TEXT['INSTALLED'] : $TEXT['NOT_INSTALLED'],
+							'status'	=> $status
+						);
+
+						// increase counter if required
+						if (!$status) $failed_checks++;
+					}
+				}
+				break;
+
+			case 'PHP_SETTINGS':
+				if (is_array($PRECHECK['PHP_SETTINGS'])) {
+					foreach($PRECHECK['PHP_SETTINGS'] as $setting => $value) {
+						$actual_setting = ($temp = ini_get($setting)) ? $temp : 0;
+						$status = ($actual_setting == $value);
+					
+						$msg[] = array(
+							'check'		=> '&nbsp; '. ($setting),
+							'required'	=> $value,
+							'actual'	=> $actual_setting,
+							'status'	=> $status
+						);
+
+						// increase counter if required
+						if (!$status) $failed_checks++;
+					}
+				}
+				break;
+
+			case 'CUSTOM_CHECKS':
+				if (is_array($PRECHECK['CUSTOM_CHECKS'])) {
+					foreach($PRECHECK['CUSTOM_CHECKS'] as $key => $values) {
+						$status = (true === array_key_exists('STATUS', $values )) ? $values['STATUS'] : false;
+						$msg[] = array(
+							'check'		=> $key,
+							'required'	=> $values['REQUIRED'],
+							'actual'	=> $values['ACTUAL'],
+							'status'	=> $status
+						);
+					}
+
+					// increase counter if required
+					if (!$status) $failed_checks++;
+				}
+				break;
+		}
+	}
+
+	// leave if all requirements are fullfilled
+	if ($failed_checks == 0) return;
+	
+	// output summary table with requirements not fullfilled
+	echo <<< EOT
+	<h2>{$HEADING['ADDON_PRECHECK_FAILED']}</h2>
+	<p>{$MESSAGE['ADDON']['PRECHECK_FAILED']}</p> 
+
+	<table width="700px" cellpadding="4" border="0" style="margin: 0.5em; border-collapse: collapse; border: 1px solid silver;">
+	<tr>
+		<th>{$TEXT['REQUIREMENT']}:</th>
+		<th>{$TEXT['REQUIRED']}:</th>
+		<th>{$TEXT['CURRENT']}:</th>
+	</tr>
+EOT;
+
+	foreach($msg as $check) {
+		echo '<tr>';
+		$style = $check['status'] ? 'color: #46882B;' : 'color: #C00;';
+		foreach($check as $key => $value) {
+			if ($key == 'status') continue;
+			
+			echo '<td style="' . $style . '">' . $value . '</td>';
+		}
+		echo '</tr>';
+	}
+	echo '</table>';
+
+	// delete the temp unzip directory
+	rm_full_dir($temp_path);	
+
+	// delete the temporary zip file of the Add-on
+	if(file_exists($temp_addon_file)) { unlink($temp_addon_file); }	
+	
+	// output status message and die
+	$admin->print_error('');
+}
+
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/framework/charsets_table.php
===================================================================
--- branches/2.8.x/wb/framework/charsets_table.php	(revision 1419)
+++ branches/2.8.x/wb/framework/charsets_table.php	(revision 1420)
@@ -23,10 +23,8 @@
 
 */
 
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 global $iso_8859_2_to_utf8;
 $iso_8859_2_to_utf8 = array(
Index: branches/2.8.x/wb/framework/class.frontend.php
===================================================================
--- branches/2.8.x/wb/framework/class.frontend.php	(revision 1419)
+++ branches/2.8.x/wb/framework/class.frontend.php	(revision 1420)
@@ -1,439 +1,437 @@
-<?php
-/**
- *
- * @category        frontend
- * @package         framework
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
-*/
-
-if(!defined('WB_PATH')) {
-	header('Location: ../index.php');
-	exit(0);
-}
-
-require_once(WB_PATH.'/framework/class.wb.php');
-require_once(WB_PATH.'/framework/SecureForm.php');
-
-class frontend extends wb {
-	// defaults
-	public $default_link,$default_page_id;
-	// when multiple blocks are used, show home page blocks on 
-	// pages where no content is defined (search, login, ...)
-	public $default_block_content=true;
-
-	// page details
-	// page database row
-	public $page;
-	public $page_id,$page_title,$menu_title,$parent,$root_parent,$level,$visibility;
-	public $page_description,$page_keywords,$page_link;
-	public $page_trail=array();
-	
-	public $page_access_denied;
-	public $page_no_active_sections;
-	
-	// website settings
-	public $website_title,$website_description,$website_keywords,$website_header,$website_footer;
-
-	// ugly database stuff
-	public $extra_where_sql, $sql_where_language;
-	
-	public function __construct() {
-		parent::__construct(SecureForm::FRONTEND);
-	}
-
-	public function page_select() {
-		global $page_id,$no_intro;
-		global $database;
-		// We have no page id and are supposed to show the intro page
-		if((INTRO_PAGE AND !isset($no_intro)) AND (!isset($page_id) OR !is_numeric($page_id))) {
-			// Since we have no page id check if we should go to intro page or default page
-			// Get intro page content
-			$filename = WB_PATH.PAGES_DIRECTORY.'/intro'.PAGE_EXTENSION;
-			if(file_exists($filename)) {
-				$handle = @fopen($filename, "r");
-				$content = @fread($handle, filesize($filename));
-				@fclose($handle);
-				$this->preprocess($content);
-				header("Location: ".WB_URL.PAGES_DIRECTORY."/intro".PAGE_EXTENSION."");   // send intro.php as header to allow parsing of php statements
-				echo ($content);
-				return false;
-			}
-		}
-		// Check if we should add page language sql code
-		if(PAGE_LANGUAGES) {
-			$this->sql_where_language = " AND language = '".LANGUAGE."'";
-		}
-		// Get default page
-		// Check for a page id
-		$table_p = TABLE_PREFIX.'pages';
-		$table_s = TABLE_PREFIX.'sections';
-		$now = time();
-		$query_default = "
-			SELECT `p`.`page_id`, `link`
-			FROM `$table_p` AS `p` INNER JOIN `$table_s` USING(`page_id`)
-			WHERE `parent` = '0' AND `visibility` = 'public'
-			AND (($now>=`publ_start` OR `publ_start`=0) AND ($now<=`publ_end` OR `publ_end`=0))
-			$this->sql_where_language
-			ORDER BY `p`.`position` ASC LIMIT 1";
-		$get_default = $database->query($query_default);
-		$default_num_rows = $get_default->numRows();
-		if(!isset($page_id) OR !is_numeric($page_id)){
-			// Go to or show default page
-			if($default_num_rows > 0) {
-				$fetch_default = $get_default->fetchRow();
-				$this->default_link = $fetch_default['link'];
-				$this->default_page_id = $fetch_default['page_id'];
-				// Check if we should redirect or include page inline
-				if(HOMEPAGE_REDIRECTION) {
-					// Redirect to page
-					header("Location: ".$this->page_link($this->default_link));
-					exit();
-				} else {
-					// Include page inline
-					$this->page_id = $this->default_page_id;
-				}
-			} else {
-		   		// No pages have been added, so print under construction page
-				$this->print_under_construction();
-				exit();
-			}
-		} else {
-			$this->page_id=$page_id;
-		}
-		// Get default page link
-		if(!isset($fetch_default)) {
-		  	$fetch_default = $get_default->fetchRow();
-	 		$this->default_link = $fetch_default['link'];
-			$this->default_page_id = $fetch_default['page_id'];
-		}
-		return true;
-	}
-
-	public function get_page_details() {
-		global $database;
-	    if($this->page_id != 0) {
-			// Query page details
-			$query_page = "SELECT * FROM ".TABLE_PREFIX."pages WHERE page_id = '{$this->page_id}'";
-			$get_page = $database->query($query_page);
-			// Make sure page was found in database
-			if($get_page->numRows() == 0) {
-				// Print page not found message
-				exit("Page not found");
-			}
-			// Fetch page details
-			$this->page = $get_page->fetchRow();
-			// Check if the page language is also the selected language. If not, send headers again.
-			if ($this->page['language']!=LANGUAGE) {
-				if(isset($_SERVER['QUERY_STRING']) && $_SERVER['QUERY_STRING'] != '') { // check if there is an query-string
-					header('Location: '.$this->page_link($this->page['link']).'?'.$_SERVER['QUERY_STRING'].'&lang='.$this->page['language']);
-				} else {
-					header('Location: '.$this->page_link($this->page['link']).'?lang='.$this->page['language']);
-				}
-				exit();
-			}
-			// Begin code to set details as either variables of constants
-			// Page ID
-			if(!defined('PAGE_ID')) {define('PAGE_ID', $this->page['page_id']);}
-			// Page Title
-			if(!defined('PAGE_TITLE')) {define('PAGE_TITLE', $this->page['page_title']);}
-			$this->page_title=PAGE_TITLE;
-			// Menu Title
-			$menu_title = $this->page['menu_title'];
-			if($menu_title != '') {
-				if(!defined('MENU_TITLE')) {define('MENU_TITLE', $menu_title);}
-			} else {
-				if(!defined('MENU_TITLE')) {define('MENU_TITLE', PAGE_TITLE);}
-			}
-			$this->menu_title = MENU_TITLE;
-			// Page parent
-			if(!defined('PARENT')) {define('PARENT', $this->page['parent']);}
-			$this->parent=$this->page['parent'];
-			// Page root parent
-			if(!defined('ROOT_PARENT')) {define('ROOT_PARENT', $this->page['root_parent']);}
-			$this->root_parent=$this->page['root_parent'];
-			// Page level
-			if(!defined('LEVEL')) {define('LEVEL', $this->page['level']);}
-			$this->level=$this->page['level'];
-			// Page visibility
-			if(!defined('VISIBILITY')) {define('VISIBILITY', $this->page['visibility']);}
-			$this->visibility=$this->page['visibility'];
-			// Page trail
-			foreach(explode(',', $this->page['page_trail']) AS $pid) {
-				$this->page_trail[$pid]=$pid;
-			}
-			// Page description
-			$this->page_description=$this->page['description'];
-			if($this->page_description != '') {
-				define('PAGE_DESCRIPTION', $this->page_description);
-			} else {
-				define('PAGE_DESCRIPTION', WEBSITE_DESCRIPTION);
-			}
-			// Page keywords
-			$this->page_keywords=$this->page['keywords'];
-			// Page link
-			$this->link=$this->page_link($this->page['link']);
-
-		// End code to set details as either variables of constants
-		}
-
-		// Figure out what template to use
-		if(!defined('TEMPLATE')) {
-			if(isset($this->page['template']) AND $this->page['template'] != '') {
-				if(file_exists(WB_PATH.'/templates/'.$this->page['template'].'/index.php')) {
-					define('TEMPLATE', $this->page['template']);
-				} else {
-					define('TEMPLATE', DEFAULT_TEMPLATE);
-				}
-			} else {
-				define('TEMPLATE', DEFAULT_TEMPLATE);
-			}
-		}
-		// Set the template dir
-		define('TEMPLATE_DIR', WB_URL.'/templates/'.TEMPLATE);
-
-		// Check if user is allowed to view this page
-		if($this->page && $this->page_is_visible($this->page) == false) {
-			if(VISIBILITY == 'deleted' OR VISIBILITY == 'none') {
-				// User isnt allowed on this page so tell them
-				$this->page_access_denied=true;
-			} elseif(VISIBILITY == 'private' OR VISIBILITY == 'registered') {
-				// Check if the user is authenticated
-				if($this->is_authenticated() == false) {
-					// User needs to login first
-					header("Location: ".WB_URL."/account/login.php?redirect=".$this->link);
-					exit(0);
-				} else {
-					// User isnt allowed on this page so tell them
-					$this->page_access_denied=true;
-				}
-				
-			}
-		}
-		// check if there is at least one active section
-		if($this->page && $this->page_is_active($this->page) == false) {
-			$this->page_no_active_sections=true;
-		}
-	}
-
-	public function get_website_settings()
-    {
-		global $database;
-
-		// set visibility SQL code
-		// never show no-vis, hidden or deleted pages
-		$this->extra_where_sql = "visibility != 'none' AND visibility != 'hidden' AND visibility != 'deleted'";
-		// Set extra private sql code
-		if($this->is_authenticated()==false) {
-			// if user is not authenticated, don't show private pages either
-			$this->extra_where_sql .= " AND visibility != 'private'";
-			// and 'registered' without frontend login doesn't make much sense!
-			if (FRONTEND_LOGIN==false) {
-				$this->extra_where_sql .= " AND visibility != 'registered'";
-			}
-		}
-		$this->extra_where_sql .= $this->sql_where_language;
-
-		// Work-out if any possible in-line search boxes should be shown
-		if(SEARCH == 'public') {
-			define('SHOW_SEARCH', true);
-		} elseif(SEARCH == 'private' AND VISIBILITY == 'private') {
-			define('SHOW_SEARCH', true);
-		} elseif(SEARCH == 'private' AND $this->is_authenticated() == true) {
-			define('SHOW_SEARCH', true);
-		} elseif(SEARCH == 'registered' AND $this->is_authenticated() == true) {
-			define('SHOW_SEARCH', true);	
-		} else {
-			define('SHOW_SEARCH', false);
-		}
-		// Work-out if menu should be shown
-		if(!defined('SHOW_MENU')) {
-			define('SHOW_MENU', true);
-		}
-		// Work-out if login menu constants should be set
-		if(FRONTEND_LOGIN) {
-			// Set login menu constants
-			define('LOGIN_URL', WB_URL.'/account/login.php');
-			define('LOGOUT_URL', WB_URL.'/account/logout.php');
-			define('FORGOT_URL', WB_URL.'/account/forgot.php');
-			define('PREFERENCES_URL', WB_URL.'/account/preferences.php');
-			define('SIGNUP_URL', WB_URL.'/account/signup.php');
-		}
-	}
-
-/*
- * replace all "[wblink{page_id}]" with real links
- * @param string &$content : reference to global $content
- * @return void
- * @history 100216 17:00:00 optimise errorhandling, speed, SQL-strict
- */
-	public function preprocess(&$content)
-	{
-		global $database;
-		$replace_list = array();
-		$pattern = '/\[wblink([0-9]+)\]/isU';
-		if(preg_match_all($pattern,$content,$ids))
-		{
-			foreach($ids[1] as $key => $page_id)
-			{
-				$replace_list[$page_id] = $ids[0][$key];
-			}
-			foreach($replace_list as $page_id => $tag)
-			{
-				$sql = 'SELECT `link` FROM `'.TABLE_PREFIX.'pages` WHERE `page_id` = '.(int)$page_id;
-				$link = $database->get_one($sql);
-				if(!is_null($link))
-				{
-					$link = $this->page_link($link);
-					$content = str_replace($tag, $link, $content);
-				}
-			}
-		}
-	}
-
-/*
-	function preprocess(&$content) {
-		global $database;
-		// Replace [wblink--PAGE_ID--] with real link
-		$pattern = '/\[wblink(.+?)\]/s';
-		preg_match_all($pattern,$content,$ids);
-		foreach($ids[1] AS $page_id) {
-			$pattern = '/\[wblink'.$page_id.'\]/s';
-			// Get page link
-			$get_link = $database->query("SELECT link FROM ".TABLE_PREFIX."pages WHERE page_id = '$page_id' LIMIT 1");
-			$fetch_link = $get_link->fetchRow();
-			$link = $this->page_link($fetch_link['link']);
-			$content = preg_replace($pattern,$link,$content);
-		}
-	}
-*/
-	public function menu() {
-		global $wb;
-	   if (!isset($wb->menu_number)) {
-	   	$wb->menu_number = 1;
-	   }
-	   if (!isset($wb->menu_start_level)) {
-	   	$wb->menu_start_level = 0;
-	   }
-	   if (!isset($wb->menu_recurse)) {
-	   	$wb->menu_recurse = -1;
-	   }
-	   if (!isset($wb->menu_collapse)) {
-	   	$wb->menu_collapse = true;
-	   }
-	   if (!isset($wb->menu_item_template)) {
-	   	$wb->menu_item_template = '<li><span[class]>[a] [menu_title] [/a]</span>';
-	   }
-	   if (!isset($wb->menu_item_footer)) {
-	   	$wb->menu_item_footer = '</li>';
-	   }
-	   if (!isset($wb->menu_header)) {
-	   	$wb->menu_header = '<ul>';
-	   }
-	   if (!isset($wb->menu_footer)) {
-	   	$wb->menu_footer = '</ul>';
-	   }
-	   if (!isset($wb->menu_default_class)) {
-	   	$wb->menu_default_class = ' class="menu_default"';
-	   }
-	   if (!isset($wb->menu_current_class)) {
-	   	$wb->menu_current_class = ' class="menu_current"';
-	   }
-	   if (!isset($wb->menu_parent)) {
-	   	$wb->menu_parent = 0;
-	   }
-	   $wb->show_menu();
-	}
-	
-	public function show_menu() {
-		global $database;
-		if ($this->menu_start_level>0) {
-			$key_array=array_keys($this->page_trail);
-			if (isset($key_array[$this->menu_start_level-1])) {
-				$real_start=$key_array[$this->menu_start_level-1];
-				$this->menu_parent=$real_start;
-				$this->menu_start_level=0;
-			} else {
-				return;
-			}
-		}
-		if ($this->menu_recurse==0)
-	       return;
-		// Check if we should add menu number check to query
-		if($this->menu_parent == 0) {
-			$menu_number = "menu = '$this->menu_number'";
-		} else {
-			$menu_number = '1';
-		}
-		// Query pages
-		$query_menu = $database->query("SELECT page_id,menu_title,page_title,link,target,level,visibility,viewing_groups,viewing_users FROM ".TABLE_PREFIX."pages WHERE parent = '$this->menu_parent' AND $menu_number AND $this->extra_where_sql ORDER BY position ASC");
-		// Check if there are any pages to show
-		if($query_menu->numRows() > 0) {
-			// Print menu header
-			echo "\n".$this->menu_header;
-			// Loop through pages
-			while($page = $query_menu->fetchRow()) {
-				// check whether to show this menu-link
-				if($this->page_is_active($page)==false && $page['link']!=$this->default_link && !INTRO_PAGE) {
-					continue; // no active sections
-				}
-				if($this->page_is_visible($page)==false) {
-					if($page['visibility'] != 'registered') // special case: page_to_visible() check wheter to show the page contents, but the menu should be visible allways
-						continue;
-				}
-				// Create vars
-				$vars = array('[class]','[a]', '[/a]', '[menu_title]', '[page_title]');
-				// Work-out class
-				if($page['page_id'] == PAGE_ID) {
-					$class = $this->menu_current_class;
-				} else {
-					$class = $this->menu_default_class;
-				}
-				// Check if link is same as first page link, and if so change to WB URL
-				if($page['link'] == $this->default_link AND !INTRO_PAGE) {
-					$link = WB_URL;
-				} else {
-					$link = $this->page_link($page['link']);
-				}
-				// Create values
-				$values = array($class,'<a href="'.$link.'" target="'.$page['target'].'" '.$class.'>', '</a>', $page['menu_title'], $page['page_title']);
-				// Replace vars with value and print
-				echo "\n".str_replace($vars, $values, $this->menu_item_template);
-				// Generate sub-menu
-				if($this->menu_collapse==false OR ($this->menu_collapse==true AND isset($this->page_trail[$page['page_id']]))) {
-					$this->menu_recurse--;
-					$this->menu_parent=$page['page_id'];
-					$this->show_menu();
-				}
-				echo "\n".$this->menu_item_footer;
-			}
-			// Print menu footer
-			echo "\n".$this->menu_footer;
-		}
-	}
-
-
-	// Function to show the "Under Construction" page
-	public function print_under_construction() {
-		global $MESSAGE;
-		require_once(WB_PATH.'/languages/'.DEFAULT_LANGUAGE.'.php');
-		echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-		<head><title>'.$MESSAGE['GENERIC']['WEBSITE_UNDER_CONSTRUCTION'].'</title>
-		<style type="text/css"><!-- body{ font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 12px; background-image: url("'.ADMIN_URL.'/interface/background.png");background-repeat: repeat-x; background-color: #A8BCCB; text-align: center; }
-		h1 { margin: 0; padding: 0; font-size: 18px; color: #000; text-transform: uppercase;
-}--></style></head><body>
-		<br /><h1>'.$MESSAGE['GENERIC']['WEBSITE_UNDER_CONSTRUCTION'].'</h1><br />
-		'.$MESSAGE['GENERIC']['PLEASE_CHECK_BACK_SOON'].'</body></html>';
-	}
-}
-
+<?php
+/**
+ *
+ * @category        frontend
+ * @package         framework
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+*/
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+require_once(WB_PATH.'/framework/class.wb.php');
+require_once(WB_PATH.'/framework/SecureForm.php');
+
+class frontend extends wb {
+	// defaults
+	public $default_link,$default_page_id;
+	// when multiple blocks are used, show home page blocks on 
+	// pages where no content is defined (search, login, ...)
+	public $default_block_content=true;
+
+	// page details
+	// page database row
+	public $page;
+	public $page_id,$page_title,$menu_title,$parent,$root_parent,$level,$visibility;
+	public $page_description,$page_keywords,$page_link;
+	public $page_trail=array();
+	
+	public $page_access_denied;
+	public $page_no_active_sections;
+	
+	// website settings
+	public $website_title,$website_description,$website_keywords,$website_header,$website_footer;
+
+	// ugly database stuff
+	public $extra_where_sql, $sql_where_language;
+	
+	public function __construct() {
+		parent::__construct(SecureForm::FRONTEND);
+	}
+
+	public function page_select() {
+		global $page_id,$no_intro;
+		global $database;
+		// We have no page id and are supposed to show the intro page
+		if((INTRO_PAGE AND !isset($no_intro)) AND (!isset($page_id) OR !is_numeric($page_id))) {
+			// Since we have no page id check if we should go to intro page or default page
+			// Get intro page content
+			$filename = WB_PATH.PAGES_DIRECTORY.'/intro'.PAGE_EXTENSION;
+			if(file_exists($filename)) {
+				$handle = @fopen($filename, "r");
+				$content = @fread($handle, filesize($filename));
+				@fclose($handle);
+				$this->preprocess($content);
+				header("Location: ".WB_URL.PAGES_DIRECTORY."/intro".PAGE_EXTENSION."");   // send intro.php as header to allow parsing of php statements
+				echo ($content);
+				return false;
+			}
+		}
+		// Check if we should add page language sql code
+		if(PAGE_LANGUAGES) {
+			$this->sql_where_language = " AND language = '".LANGUAGE."'";
+		}
+		// Get default page
+		// Check for a page id
+		$table_p = TABLE_PREFIX.'pages';
+		$table_s = TABLE_PREFIX.'sections';
+		$now = time();
+		$query_default = "
+			SELECT `p`.`page_id`, `link`
+			FROM `$table_p` AS `p` INNER JOIN `$table_s` USING(`page_id`)
+			WHERE `parent` = '0' AND `visibility` = 'public'
+			AND (($now>=`publ_start` OR `publ_start`=0) AND ($now<=`publ_end` OR `publ_end`=0))
+			$this->sql_where_language
+			ORDER BY `p`.`position` ASC LIMIT 1";
+		$get_default = $database->query($query_default);
+		$default_num_rows = $get_default->numRows();
+		if(!isset($page_id) OR !is_numeric($page_id)){
+			// Go to or show default page
+			if($default_num_rows > 0) {
+				$fetch_default = $get_default->fetchRow();
+				$this->default_link = $fetch_default['link'];
+				$this->default_page_id = $fetch_default['page_id'];
+				// Check if we should redirect or include page inline
+				if(HOMEPAGE_REDIRECTION) {
+					// Redirect to page
+					header("Location: ".$this->page_link($this->default_link));
+					exit();
+				} else {
+					// Include page inline
+					$this->page_id = $this->default_page_id;
+				}
+			} else {
+		   		// No pages have been added, so print under construction page
+				$this->print_under_construction();
+				exit();
+			}
+		} else {
+			$this->page_id=$page_id;
+		}
+		// Get default page link
+		if(!isset($fetch_default)) {
+		  	$fetch_default = $get_default->fetchRow();
+	 		$this->default_link = $fetch_default['link'];
+			$this->default_page_id = $fetch_default['page_id'];
+		}
+		return true;
+	}
+
+	public function get_page_details() {
+		global $database;
+	    if($this->page_id != 0) {
+			// Query page details
+			$query_page = "SELECT * FROM ".TABLE_PREFIX."pages WHERE page_id = '{$this->page_id}'";
+			$get_page = $database->query($query_page);
+			// Make sure page was found in database
+			if($get_page->numRows() == 0) {
+				// Print page not found message
+				exit("Page not found");
+			}
+			// Fetch page details
+			$this->page = $get_page->fetchRow();
+			// Check if the page language is also the selected language. If not, send headers again.
+			if ($this->page['language']!=LANGUAGE) {
+				if(isset($_SERVER['QUERY_STRING']) && $_SERVER['QUERY_STRING'] != '') { // check if there is an query-string
+					header('Location: '.$this->page_link($this->page['link']).'?'.$_SERVER['QUERY_STRING'].'&lang='.$this->page['language']);
+				} else {
+					header('Location: '.$this->page_link($this->page['link']).'?lang='.$this->page['language']);
+				}
+				exit();
+			}
+			// Begin code to set details as either variables of constants
+			// Page ID
+			if(!defined('PAGE_ID')) {define('PAGE_ID', $this->page['page_id']);}
+			// Page Title
+			if(!defined('PAGE_TITLE')) {define('PAGE_TITLE', $this->page['page_title']);}
+			$this->page_title=PAGE_TITLE;
+			// Menu Title
+			$menu_title = $this->page['menu_title'];
+			if($menu_title != '') {
+				if(!defined('MENU_TITLE')) {define('MENU_TITLE', $menu_title);}
+			} else {
+				if(!defined('MENU_TITLE')) {define('MENU_TITLE', PAGE_TITLE);}
+			}
+			$this->menu_title = MENU_TITLE;
+			// Page parent
+			if(!defined('PARENT')) {define('PARENT', $this->page['parent']);}
+			$this->parent=$this->page['parent'];
+			// Page root parent
+			if(!defined('ROOT_PARENT')) {define('ROOT_PARENT', $this->page['root_parent']);}
+			$this->root_parent=$this->page['root_parent'];
+			// Page level
+			if(!defined('LEVEL')) {define('LEVEL', $this->page['level']);}
+			$this->level=$this->page['level'];
+			// Page visibility
+			if(!defined('VISIBILITY')) {define('VISIBILITY', $this->page['visibility']);}
+			$this->visibility=$this->page['visibility'];
+			// Page trail
+			foreach(explode(',', $this->page['page_trail']) AS $pid) {
+				$this->page_trail[$pid]=$pid;
+			}
+			// Page description
+			$this->page_description=$this->page['description'];
+			if($this->page_description != '') {
+				define('PAGE_DESCRIPTION', $this->page_description);
+			} else {
+				define('PAGE_DESCRIPTION', WEBSITE_DESCRIPTION);
+			}
+			// Page keywords
+			$this->page_keywords=$this->page['keywords'];
+			// Page link
+			$this->link=$this->page_link($this->page['link']);
+
+		// End code to set details as either variables of constants
+		}
+
+		// Figure out what template to use
+		if(!defined('TEMPLATE')) {
+			if(isset($this->page['template']) AND $this->page['template'] != '') {
+				if(file_exists(WB_PATH.'/templates/'.$this->page['template'].'/index.php')) {
+					define('TEMPLATE', $this->page['template']);
+				} else {
+					define('TEMPLATE', DEFAULT_TEMPLATE);
+				}
+			} else {
+				define('TEMPLATE', DEFAULT_TEMPLATE);
+			}
+		}
+		// Set the template dir
+		define('TEMPLATE_DIR', WB_URL.'/templates/'.TEMPLATE);
+
+		// Check if user is allowed to view this page
+		if($this->page && $this->page_is_visible($this->page) == false) {
+			if(VISIBILITY == 'deleted' OR VISIBILITY == 'none') {
+				// User isnt allowed on this page so tell them
+				$this->page_access_denied=true;
+			} elseif(VISIBILITY == 'private' OR VISIBILITY == 'registered') {
+				// Check if the user is authenticated
+				if($this->is_authenticated() == false) {
+					// User needs to login first
+					header("Location: ".WB_URL."/account/login.php?redirect=".$this->link);
+					exit(0);
+				} else {
+					// User isnt allowed on this page so tell them
+					$this->page_access_denied=true;
+				}
+				
+			}
+		}
+		// check if there is at least one active section
+		if($this->page && $this->page_is_active($this->page) == false) {
+			$this->page_no_active_sections=true;
+		}
+	}
+
+	public function get_website_settings()
+    {
+		global $database;
+
+		// set visibility SQL code
+		// never show no-vis, hidden or deleted pages
+		$this->extra_where_sql = "visibility != 'none' AND visibility != 'hidden' AND visibility != 'deleted'";
+		// Set extra private sql code
+		if($this->is_authenticated()==false) {
+			// if user is not authenticated, don't show private pages either
+			$this->extra_where_sql .= " AND visibility != 'private'";
+			// and 'registered' without frontend login doesn't make much sense!
+			if (FRONTEND_LOGIN==false) {
+				$this->extra_where_sql .= " AND visibility != 'registered'";
+			}
+		}
+		$this->extra_where_sql .= $this->sql_where_language;
+
+		// Work-out if any possible in-line search boxes should be shown
+		if(SEARCH == 'public') {
+			define('SHOW_SEARCH', true);
+		} elseif(SEARCH == 'private' AND VISIBILITY == 'private') {
+			define('SHOW_SEARCH', true);
+		} elseif(SEARCH == 'private' AND $this->is_authenticated() == true) {
+			define('SHOW_SEARCH', true);
+		} elseif(SEARCH == 'registered' AND $this->is_authenticated() == true) {
+			define('SHOW_SEARCH', true);	
+		} else {
+			define('SHOW_SEARCH', false);
+		}
+		// Work-out if menu should be shown
+		if(!defined('SHOW_MENU')) {
+			define('SHOW_MENU', true);
+		}
+		// Work-out if login menu constants should be set
+		if(FRONTEND_LOGIN) {
+			// Set login menu constants
+			define('LOGIN_URL', WB_URL.'/account/login.php');
+			define('LOGOUT_URL', WB_URL.'/account/logout.php');
+			define('FORGOT_URL', WB_URL.'/account/forgot.php');
+			define('PREFERENCES_URL', WB_URL.'/account/preferences.php');
+			define('SIGNUP_URL', WB_URL.'/account/signup.php');
+		}
+	}
+
+/*
+ * replace all "[wblink{page_id}]" with real links
+ * @param string &$content : reference to global $content
+ * @return void
+ * @history 100216 17:00:00 optimise errorhandling, speed, SQL-strict
+ */
+	public function preprocess(&$content)
+	{
+		global $database;
+		$replace_list = array();
+		$pattern = '/\[wblink([0-9]+)\]/isU';
+		if(preg_match_all($pattern,$content,$ids))
+		{
+			foreach($ids[1] as $key => $page_id)
+			{
+				$replace_list[$page_id] = $ids[0][$key];
+			}
+			foreach($replace_list as $page_id => $tag)
+			{
+				$sql = 'SELECT `link` FROM `'.TABLE_PREFIX.'pages` WHERE `page_id` = '.(int)$page_id;
+				$link = $database->get_one($sql);
+				if(!is_null($link))
+				{
+					$link = $this->page_link($link);
+					$content = str_replace($tag, $link, $content);
+				}
+			}
+		}
+	}
+
+/*
+	function preprocess(&$content) {
+		global $database;
+		// Replace [wblink--PAGE_ID--] with real link
+		$pattern = '/\[wblink(.+?)\]/s';
+		preg_match_all($pattern,$content,$ids);
+		foreach($ids[1] AS $page_id) {
+			$pattern = '/\[wblink'.$page_id.'\]/s';
+			// Get page link
+			$get_link = $database->query("SELECT link FROM ".TABLE_PREFIX."pages WHERE page_id = '$page_id' LIMIT 1");
+			$fetch_link = $get_link->fetchRow();
+			$link = $this->page_link($fetch_link['link']);
+			$content = preg_replace($pattern,$link,$content);
+		}
+	}
+*/
+	public function menu() {
+		global $wb;
+	   if (!isset($wb->menu_number)) {
+	   	$wb->menu_number = 1;
+	   }
+	   if (!isset($wb->menu_start_level)) {
+	   	$wb->menu_start_level = 0;
+	   }
+	   if (!isset($wb->menu_recurse)) {
+	   	$wb->menu_recurse = -1;
+	   }
+	   if (!isset($wb->menu_collapse)) {
+	   	$wb->menu_collapse = true;
+	   }
+	   if (!isset($wb->menu_item_template)) {
+	   	$wb->menu_item_template = '<li><span[class]>[a] [menu_title] [/a]</span>';
+	   }
+	   if (!isset($wb->menu_item_footer)) {
+	   	$wb->menu_item_footer = '</li>';
+	   }
+	   if (!isset($wb->menu_header)) {
+	   	$wb->menu_header = '<ul>';
+	   }
+	   if (!isset($wb->menu_footer)) {
+	   	$wb->menu_footer = '</ul>';
+	   }
+	   if (!isset($wb->menu_default_class)) {
+	   	$wb->menu_default_class = ' class="menu_default"';
+	   }
+	   if (!isset($wb->menu_current_class)) {
+	   	$wb->menu_current_class = ' class="menu_current"';
+	   }
+	   if (!isset($wb->menu_parent)) {
+	   	$wb->menu_parent = 0;
+	   }
+	   $wb->show_menu();
+	}
+	
+	public function show_menu() {
+		global $database;
+		if ($this->menu_start_level>0) {
+			$key_array=array_keys($this->page_trail);
+			if (isset($key_array[$this->menu_start_level-1])) {
+				$real_start=$key_array[$this->menu_start_level-1];
+				$this->menu_parent=$real_start;
+				$this->menu_start_level=0;
+			} else {
+				return;
+			}
+		}
+		if ($this->menu_recurse==0)
+	       return;
+		// Check if we should add menu number check to query
+		if($this->menu_parent == 0) {
+			$menu_number = "menu = '$this->menu_number'";
+		} else {
+			$menu_number = '1';
+		}
+		// Query pages
+		$query_menu = $database->query("SELECT page_id,menu_title,page_title,link,target,level,visibility,viewing_groups,viewing_users FROM ".TABLE_PREFIX."pages WHERE parent = '$this->menu_parent' AND $menu_number AND $this->extra_where_sql ORDER BY position ASC");
+		// Check if there are any pages to show
+		if($query_menu->numRows() > 0) {
+			// Print menu header
+			echo "\n".$this->menu_header;
+			// Loop through pages
+			while($page = $query_menu->fetchRow()) {
+				// check whether to show this menu-link
+				if($this->page_is_active($page)==false && $page['link']!=$this->default_link && !INTRO_PAGE) {
+					continue; // no active sections
+				}
+				if($this->page_is_visible($page)==false) {
+					if($page['visibility'] != 'registered') // special case: page_to_visible() check wheter to show the page contents, but the menu should be visible allways
+						continue;
+				}
+				// Create vars
+				$vars = array('[class]','[a]', '[/a]', '[menu_title]', '[page_title]');
+				// Work-out class
+				if($page['page_id'] == PAGE_ID) {
+					$class = $this->menu_current_class;
+				} else {
+					$class = $this->menu_default_class;
+				}
+				// Check if link is same as first page link, and if so change to WB URL
+				if($page['link'] == $this->default_link AND !INTRO_PAGE) {
+					$link = WB_URL;
+				} else {
+					$link = $this->page_link($page['link']);
+				}
+				// Create values
+				$values = array($class,'<a href="'.$link.'" target="'.$page['target'].'" '.$class.'>', '</a>', $page['menu_title'], $page['page_title']);
+				// Replace vars with value and print
+				echo "\n".str_replace($vars, $values, $this->menu_item_template);
+				// Generate sub-menu
+				if($this->menu_collapse==false OR ($this->menu_collapse==true AND isset($this->page_trail[$page['page_id']]))) {
+					$this->menu_recurse--;
+					$this->menu_parent=$page['page_id'];
+					$this->show_menu();
+				}
+				echo "\n".$this->menu_item_footer;
+			}
+			// Print menu footer
+			echo "\n".$this->menu_footer;
+		}
+	}
+
+
+	// Function to show the "Under Construction" page
+	public function print_under_construction() {
+		global $MESSAGE;
+		require_once(WB_PATH.'/languages/'.DEFAULT_LANGUAGE.'.php');
+		echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+		<head><title>'.$MESSAGE['GENERIC']['WEBSITE_UNDER_CONSTRUCTION'].'</title>
+		<style type="text/css"><!-- body{ font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 12px; background-image: url("'.ADMIN_URL.'/interface/background.png");background-repeat: repeat-x; background-color: #A8BCCB; text-align: center; }
+		h1 { margin: 0; padding: 0; font-size: 18px; color: #000; text-transform: uppercase;
+}--></style></head><body>
+		<br /><h1>'.$MESSAGE['GENERIC']['WEBSITE_UNDER_CONSTRUCTION'].'</h1><br />
+		'.$MESSAGE['GENERIC']['PLEASE_CHECK_BACK_SOON'].'</body></html>';
+	}
+}
+
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/framework/frontend.functions.php
===================================================================
--- branches/2.8.x/wb/framework/frontend.functions.php	(revision 1419)
+++ branches/2.8.x/wb/framework/frontend.functions.php	(revision 1420)
@@ -16,10 +16,8 @@
  *
 */
 
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 // references to objects and variables that changed their names
 
Index: branches/2.8.x/wb/search/search.php
===================================================================
--- branches/2.8.x/wb/search/search.php	(revision 1419)
+++ branches/2.8.x/wb/search/search.php	(revision 1420)
@@ -1,706 +1,704 @@
-<?php
-/**
- *
- * @category        frontend
- * @package         search
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-if(!defined('WB_URL')) {
-	header('Location: index.php');
-	exit(0);
-}
-
-// Check if search is enabled
-if(SHOW_SEARCH != true) {
-	echo $TEXT['SEARCH'].' '.$TEXT['DISABLED'];
-	return;
-}
-
-// Include the WB functions file
-require_once(WB_PATH.'/framework/functions.php');
-
-// Get search settings
-$table=TABLE_PREFIX.'search';
-$query = $database->query("SELECT value FROM $table WHERE name = 'header' LIMIT 1");
-$fetch_header = $query->fetchRow();
-$query = $database->query("SELECT value FROM $table WHERE name = 'footer' LIMIT 1");
-$fetch_footer = $query->fetchRow();
-$query = $database->query("SELECT value FROM $table WHERE name = 'results_header' LIMIT 1");
-$fetch_results_header = $query->fetchRow();
-$query = $database->query("SELECT value FROM $table WHERE name = 'results_footer' LIMIT 1");
-$fetch_results_footer = $query->fetchRow();
-$query = $database->query("SELECT value FROM $table WHERE name = 'results_loop' LIMIT 1");
-$fetch_results_loop = $query->fetchRow();
-$query = $database->query("SELECT value FROM $table WHERE name = 'no_results' LIMIT 1");
-$fetch_no_results = $query->fetchRow();
-$query = $database->query("SELECT value FROM $table WHERE name = 'module_order' LIMIT 1");
-if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value']='faqbaker,manual,wysiwyg'; }
-$search_module_order = $res['value'];
-$query = $database->query("SELECT value FROM $table WHERE name = 'max_excerpt' LIMIT 1");
-if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = '15'; }
-$search_max_excerpt = (int)($res['value']);
-if(!is_numeric($search_max_excerpt)) { $search_max_excerpt = 15; }
-$query = $database->query("SELECT value FROM $table WHERE name = 'cfg_show_description' LIMIT 1");
-if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = 'true'; }
-if($res['value'] == 'false') { $cfg_show_description = false; } else { $cfg_show_description = true; }
-$query = $database->query("SELECT value FROM $table WHERE name = 'cfg_search_description' LIMIT 1");
-if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = 'true'; }
-if($res['value'] == 'false') { $cfg_search_description = false; } else { $cfg_search_description = true; }
-$query = $database->query("SELECT value FROM $table WHERE name = 'cfg_search_keywords' LIMIT 1");
-if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = 'true'; }
-if($res['value'] == 'false') { $cfg_search_keywords = false; } else { $cfg_search_keywords = true; }
-$query = $database->query("SELECT value FROM $table WHERE name = 'cfg_enable_old_search' LIMIT 1");
-if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = 'true'; }
-if($res['value'] == 'false') { $cfg_enable_old_search = false; } else { $cfg_enable_old_search = true; }
-$query = $database->query("SELECT value FROM $table WHERE name = 'cfg_enable_flush' LIMIT 1");
-if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = 'false'; }
-if($res['value'] == 'false') { $cfg_enable_flush = false; } else { $cfg_enable_flush = true; }
-$query = $database->query("SELECT value FROM $table WHERE name = 'time_limit' LIMIT 1"); // time-limit per module
-if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = '0'; }
-$search_time_limit = (int)($res['value']);
-if($search_time_limit < 1) $search_time_limit = 0;
-
-// search-module-extension: get helper-functions
-require_once(WB_PATH.'/search/search_modext.php');
-// search-module-extension: Get "search.php" for each module, if present
-// looks in modules/module/ and modules/module_searchext/
-$search_funcs = array();$search_funcs['__before'] = array();$search_funcs['__after'] = array();
-$query = $database->query("SELECT DISTINCT directory FROM ".TABLE_PREFIX."addons WHERE type = 'module' AND directory NOT LIKE '%_searchext'");
-if($query->numRows() > 0) {
-	while($module = $query->fetchRow()) {
-		$file = WB_PATH.'/modules/'.$module['directory'].'/search.php';
-		if(!file_exists($file)) {
-			$file = WB_PATH.'/modules/'.$module['directory'].'_searchext/search.php';
-			if(!file_exists($file)) {
-				$file='';
-			}
-		}
-		if($file!='') {
-			include_once($file);
-			if(function_exists($module['directory']."_search")) {
-				$search_funcs[$module['directory']] = $module['directory']."_search";
-			}
-			if(function_exists($module['directory']."_search_before")) {
-				$search_funcs['__before'][] = $module['directory']."_search_before";
-			}
-			if(function_exists($module['directory']."_search_after")) {
-				$search_funcs['__after'][] = $module['directory']."_search_after";
-			}
-		}
-	}
-}
-
-// Get list of usernames and display names
-$query = $database->query("SELECT user_id,username,display_name FROM ".TABLE_PREFIX."users");
-$users = array('0' => array('display_name' => $TEXT['UNKNOWN'], 'username' => strtolower($TEXT['UNKNOWN'])));
-if($query->numRows() > 0) {
-	while($user = $query->fetchRow()) {
-		$users[$user['user_id']] = array('display_name' => $user['display_name'], 'username' => $user['username']);
-	}
-}
-
-// Get search language, used for special umlaut handling (DE: ß=ss, ...)
-$search_lang = '';
-if(isset($_REQUEST['search_lang'])) {
-	$search_lang = $_REQUEST['search_lang'];
-	if(!preg_match('~^[A-Z]{2}$~', $search_lang))
-		$search_lang = LANGUAGE;
-} else {
-	$search_lang = LANGUAGE;
-}
-
-// Get the path to search into. Normally left blank
-// ATTN: since wb2.7.1 the path is evaluated as SQL: LIKE "/path%" - which will find "/path.php", "/path/info.php", ...; But not "/de/path.php"
-// Add a '%' in front of each path to get SQL: LIKE "%/path%"
-/* possible values:
- * - a single path: "/en/" - search only pages whose link contains 'path' ("/en/machinery/bender-x09")
- * - a single path not to search into: "-/help" - search all, exclude /help...
- * - a bunch of alternative pathes: "/en/,%/machinery/,/docs/" - alternatives paths, seperated by comma
- * - a bunch of paths to exclude: "-/about,%/info,/jp/,/light" - search all, exclude these.
- * These different styles can't be mixed.
- */
-// ATTN: in wb2.7.0 "/en/" matched all links with "/en/" somewhere in the link: "/info/en/intro.php", "/en/info.php", ...
-// since wb2.7.1 "/en/" matches only links _starting_  with "/en/": "/en/intro/info.php"
-// use "%/en/" (or "%/en/, %/info", ...) to get the old behavior
-$search_path_SQL = '';
-$search_path = '';
-if(isset($_REQUEST['search_path'])) {
-	$search_path = addslashes(htmlspecialchars(strip_tags($wb->strip_slashes($_REQUEST['search_path'])), ENT_QUOTES));
-	if(!preg_match('~^%?[-a-zA-Z0-9_,/ ]+$~', $search_path))
-		$search_path = '';
-	if($search_path != '') {
-		$search_path_SQL = 'AND ( ';
-		$not = '';
-		$op = 'OR';
-		if($search_path[0] == '-') {
-			$not = 'NOT';
-			$op = 'AND';
-			$paths = explode(',', substr($search_path, 1) );
-		} else {
-			$paths = explode(',',$search_path);
-		}
-		$i=0;
-		foreach($paths as $p) {
-			if($i++ > 0) {
-				$search_path_SQL .= ' $op';
-			}
-			$search_path_SQL .= " link $not LIKE '".$p."%'";			
-		}
-		$search_path_SQL .= ' )';
-	}
-}
-
-// use page_languages?
-if(PAGE_LANGUAGES) {
-	$table = TABLE_PREFIX."pages";
-	$search_language_SQL_t = "AND $table.`language` = '".LANGUAGE."'";
-	$search_language_SQL = "AND `language` = '".LANGUAGE."'";
-} else {
-	$search_language_SQL_t = '';
-	$search_language_SQL = '';
-}
-
-// Get the search type
-$match = '';
-if(isset($_REQUEST['match'])) {
-	if($_REQUEST['match']=='any') $match = 'any';
-	elseif($_REQUEST['match']=='all') $match = 'all';
-	elseif($_REQUEST['match']=='exact') $match = 'exact';
-	else $match = 'all';
-} else {
-	$match = 'all';
-}
-
-// Get search string
-$search_normal_string = '';
-$search_entities_string = ''; // for SQL's LIKE
-$search_display_string = ''; // for displaying
-$search_url_string = ''; // for $_GET -- ATTN: unquoted! Will become urldecoded later
-$string = '';
-if(isset($_REQUEST['string']))
-{
-	if($match!='exact') // $string will be cleaned below 
-    {
-		$string=str_replace(',', '', $_REQUEST['string']);
-	} else {
-		$string=$_REQUEST['string'];
-	}
-    // redo possible magic quotes
-    $string = $wb->strip_slashes($string);
-    $string = preg_replace('/[ \r\n\t]+/', ' ', $string);
-    $string = trim($string);
-	// remove some bad chars
-	$string = str_replace ( array('[[',']]'),'', $string);
-	$string = preg_replace('/(^|\s+)[|.]+(?=\s+|$)/', '', $string);
-	$search_display_string = htmlspecialchars($string);
-	$search_entities_string = addslashes(umlauts_to_entities(htmlspecialchars($string)));
-	// mySQL needs four backslashes to match one in LIKE comparisons)
-	$search_entities_string = str_replace('\\\\', '\\\\\\\\', $search_entities_string);
-	// convert string to utf-8
-	$string = entities_to_umlauts($string, 'UTF-8');
-	$search_url_string = $string;
-	$string = preg_quote($string);
-	// quote ' " and /  -we need quoted / for regex
-	$search_normal_string = str_replace(array('\'','"','/'), array('\\\'','\"','\/'), $string);
-}
-// make arrays from the search_..._strings above
-if($match == 'exact')
-	$search_url_array[] = $search_url_string;
-else
-	$search_url_array = explode(' ', $search_url_string);
-$search_normal_array = array();
-$search_entities_array = array();
-if($match == 'exact') {
-	$search_normal_array[]=$search_normal_string;
-	$search_entities_array[]=$search_entities_string;
-} else {
-	$exploded_string = explode(' ', $search_normal_string);
-	// Make sure there is no blank values in the array
-	foreach($exploded_string AS $each_exploded_string) {
-		if($each_exploded_string != '') {
-			$search_normal_array[] = $each_exploded_string;
-		}
-	}
-	$exploded_string = explode(' ', $search_entities_string);
-	// Make sure there is no blank values in the array
-	foreach($exploded_string AS $each_exploded_string) {
-		if($each_exploded_string != '') {
-			$search_entities_array[] = $each_exploded_string;
-		}
-	}
-}
-// make an extra copy of search_normal_array for use in regex
-require(WB_PATH.'/search/search_convert.php');
-$search_words = array();
-foreach($search_normal_array AS $str) {
-	$str = str_replace($string_ul_umlaut, $string_ul_regex, $str);
-	$search_words[] = $str;
-}
-
-// Work-out what to do (match all words, any words, or do exact match), and do relevant with query settings
-$all_checked = '';
-$any_checked = '';
-$exact_checked = '';
-if ($match == 'any') {
-	$any_checked = ' checked="checked"';
-	$logical_operator = ' OR';
-} elseif($match == 'all') {
-	$all_checked = ' checked="checked"';
-	$logical_operator = ' AND';
-} else {
-	$exact_checked = ' checked="checked"';
-}
-
-// Replace vars in search settings with values
-$vars = array('[SEARCH_STRING]', '[WB_URL]', '[PAGE_EXTENSION]', '[TEXT_RESULTS_FOR]');
-$values = array($search_display_string, WB_URL, PAGE_EXTENSION, $TEXT['RESULTS_FOR']);
-$search_footer = str_replace($vars, $values, ($fetch_footer['value']));
-$search_results_header = str_replace($vars, $values, ($fetch_results_header['value']));
-$search_results_footer = str_replace($vars, $values, ($fetch_results_footer['value']));
-
-// Do extra vars/values replacement
-$vars = array('[SEARCH_STRING]', '[WB_URL]', '[PAGE_EXTENSION]', '[TEXT_SEARCH]', '[TEXT_ALL_WORDS]', '[TEXT_ANY_WORDS]', '[TEXT_EXACT_MATCH]', '[TEXT_MATCH]', '[TEXT_MATCHING]', '[ALL_CHECKED]', '[ANY_CHECKED]', '[EXACT_CHECKED]', '[REFERRER_ID]', '[SEARCH_PATH]');
-$values = array($search_display_string, WB_URL, PAGE_EXTENSION, $TEXT['SEARCH'], $TEXT['ALL_WORDS'], $TEXT['ANY_WORDS'], $TEXT['EXACT_MATCH'], $TEXT['MATCH'], $TEXT['MATCHING'], $all_checked, $any_checked, $exact_checked, REFERRER_ID, $search_path);
-$search_header = str_replace($vars, $values, ($fetch_header['value']));
-$vars = array('[TEXT_NO_RESULTS]');
-$values = array($TEXT['NO_RESULTS']);
-$search_no_results = str_replace($vars, $values, ($fetch_no_results['value']));
-
-/*
- * Start of output
- */
-
-// Show search header
-echo $search_header;
-// Show search results_header
-echo $search_results_header;
-
-// Work-out if the user has already entered their details or not
-if($search_normal_string != '') {
-
-	// Get modules
-	$table = TABLE_PREFIX."sections";
-	$get_modules = $database->query("SELECT DISTINCT module FROM $table WHERE module != '' ");
-	$modules = array();
-	if($get_modules->numRows() > 0) {
-		while($module = $get_modules->fetchRow()) {
-			$modules[] = $module['module'];
-		}
-	}
-	// sort module search-order
-	// get the modules from $search_module_order first ...
-	$sorted_modules = array();
-	$m = count($modules);
-	$search_modules = explode(',', $search_module_order);
-	foreach($search_modules AS $item) {
-		$item = trim($item);
-		for($i=0; $i < $m; $i++) {
-			if(isset($modules[$i]) && $modules[$i] == $item) {
-				$sorted_modules[] = $modules[$i];
-				unset($modules[$i]);
-				break;
-			}
-		}
-	}
-	// ... then add the rest
-	foreach($modules AS $item) {
-		$sorted_modules[] = $item;
-	}
-
-
-	// Use the module's search-extensions.
-	// This is somewhat slower than the orginial method.
-	
-	// call $search_funcs['__before'] first
-	$search_func_vars = array(
-		'database' => $database, // database-handle
-		'page_id' => 0,
-		'section_id' => 0,
-		'page_title' => '',
-		'page_menu_title' => '',
-		'page_description' => '',
-		'page_keywords' => '',
-		'page_link' => '',
-		'page_modified_when' => 0,
-		'page_modified_by' => 0,
-		'users' => $users, // array of known user-id/user-name
-		'search_words' => $search_words, // array of strings, prepared for regex
-		'search_match' => $match, // match-type
-		'search_url_array' => $search_url_array, // array of strings from the original search-string. ATTN: strings are not quoted!
-		'results_loop_string' => $fetch_results_loop['value'],
-		'default_max_excerpt' => $search_max_excerpt,
-		'time_limit' => $search_time_limit, // time-limit in secs
-		'search_path' => $search_path // see docu
-	);
-	foreach($search_funcs['__before'] as $func) {
-		$uf_res = call_user_func($func, $search_func_vars);
-	}
-	// now call module-based $search_funcs[]
-	$seen_pages = array(); // seen pages per module.
-	$pages_listed = array(); // seen pages.
-	if($search_max_excerpt!=0) { // skip this search if $search_max_excerpt==0
-		foreach($sorted_modules AS $module_name) {
-			$start_time = time();	// get start-time to check time-limit; not very accurate, but ok
-			$seen_pages[$module_name] = array();
-			if(!isset($search_funcs[$module_name])) {
-				continue; // there is no search_func for this module
-			}
-			// get each section for $module_name
-			$table_s = TABLE_PREFIX."sections";	
-			$table_p = TABLE_PREFIX."pages";
-			$sections_query = $database->query("
-				SELECT s.section_id, s.page_id, s.module, s.publ_start, s.publ_end,
-							 p.page_title, p.menu_title, p.link, p.description, p.keywords, p.modified_when, p.modified_by,
-							 p.visibility, p.viewing_groups, p.viewing_users
-				FROM $table_s AS s INNER JOIN $table_p AS p ON s.page_id = p.page_id
-				WHERE s.module = '$module_name' AND p.visibility NOT IN ('none','deleted') AND p.searching = '1' $search_path_SQL $search_language_SQL
-				ORDER BY s.page_id, s.position ASC
-			");
-			if($sections_query->numRows() > 0) {
-				while($res = $sections_query->fetchRow()) {
-					// check if time-limit is exceeded for this module
-					if($search_time_limit > 0 && (time()-$start_time > $search_time_limit)) {
-						break;
-					}
-					// Only show this section if it is not "out of publication-date"
-					$now = time();
-					if( !( $now<$res['publ_end'] && ($now>$res['publ_start'] || $res['publ_start']==0) ||
-						$now>$res['publ_start'] && $res['publ_end']==0) ) {
-						continue;
-					}
-					$search_func_vars = array(
-						'database' => $database,
-						'page_id' => $res['page_id'],
-						'section_id' => $res['section_id'],
-						'page_title' => $res['page_title'],
-						'page_menu_title' => $res['menu_title'],
-						'page_description' => ($cfg_show_description?$res['description']:""),
-						'page_keywords' => $res['keywords'],
-						'page_link' => $res['link'],
-						'page_modified_when' => $res['modified_when'],
-						'page_modified_by' => $res['modified_by'],
-						'users' => $users,
-						'search_words' => $search_words, // needed for preg_match
-						'search_match' => $match,
-						'search_url_array' => $search_url_array, // needed for url-string only
-						'results_loop_string' => $fetch_results_loop['value'],
-						'default_max_excerpt' => $search_max_excerpt,
-						'enable_flush' => $cfg_enable_flush,
-						'time_limit' => $search_time_limit // time-limit in secs
-					);
-					// Only show this page if we are allowed to see it
-					if($admin->page_is_visible($res) == false) {
-						if($res['visibility'] == 'registered') { // don't show excerpt
-							$search_func_vars['default_max_excerpt'] = 0;
-							$search_func_vars['page_description'] = $TEXT['REGISTERED'];
-						} else { // private
-							continue;
-						}
-					}
-					$uf_res = call_user_func($search_funcs[$module_name], $search_func_vars);
-					if($uf_res) {
-						$pages_listed[$res['page_id']] = true;
-						$seen_pages[$module_name][$res['page_id']] = true;
-					} else {
-						$seen_pages[$module_name][$res['page_id']] = true;
-					}
-				}
-			}
-		}
-	}
-	// now call $search_funcs['__after']
-	$search_func_vars = array(
-		'database' => $database, // database-handle
-		'page_id' => 0,
-		'section_id' => 0,
-		'page_title' => '',
-		'page_menu_title' => '',
-		'page_description' => '',
-		'page_keywords' => '',
-		'page_link' => '',
-		'page_modified_when' => 0,
-		'page_modified_by' => 0,
-		'users' => $users, // array of known user-id/user-name
-		'search_words' => $search_words, // array of strings, prepared for regex
-		'search_match' => $match, // match-type
-		'search_url_array' => $search_url_array, // array of strings from the original search-string. ATTN: strings are not quoted!
-		'results_loop_string' => $fetch_results_loop['value'],
-		'default_max_excerpt' => $search_max_excerpt,
-		'time_limit' => $search_time_limit, // time-limit in secs
-		'search_path' => $search_path // see docu
-	);
-	foreach($search_funcs['__after'] as $func) {
-		$uf_res = call_user_func($func, $search_func_vars);
-	}
-
-
-	// Search page details only, such as description, keywords, etc, but only of unseen pages.
-	$max_excerpt_num = 0; // we don't want excerpt here
-	$divider = ".";
-	$table = TABLE_PREFIX."pages";
-	$query_pages = $database->query("
-		SELECT page_id, page_title, menu_title, link, description, keywords, modified_when, modified_by,
-		       visibility, viewing_groups, viewing_users
-		FROM $table
-		WHERE visibility NOT IN ('none','deleted') AND searching = '1' $search_path_SQL $search_language_SQL
-	");
-	if($query_pages->numRows() > 0) {
-		while($page = $query_pages->fetchRow()) {
-			if (isset($pages_listed[$page['page_id']])) {
-				continue;
-			}
-			$func_vars = array(
-				'database' => $database,
-				'page_id' => $page['page_id'],
-				'page_title' => $page['page_title'],
-				'page_menu_title' => $page['menu_title'],
-				'page_description' => ($cfg_show_description?$page['description']:""),
-				'page_keywords' => $page['keywords'],
-				'page_link' => $page['link'],
-				'page_modified_when' => $page['modified_when'],
-				'page_modified_by' => $page['modified_by'],
-				'users' => $users,
-				'search_words' => $search_words, // needed for preg_match_all
-				'search_match' => $match,
-				'search_url_array' => $search_url_array, // needed for url-string only
-				'results_loop_string' => $fetch_results_loop['value'],
-				'default_max_excerpt' => $max_excerpt_num,
-				'enable_flush' => $cfg_enable_flush
-			);
-			// Only show this page if we are allowed to see it
-			if($admin->page_is_visible($page) == false) {
-				if($page['visibility'] != 'registered') {
-					continue;
-				} else { // page: registered, user: access denied
-					$func_vars['page_description'] = $TEXT['REGISTERED'];
-				}
-			}
-			if($admin->page_is_active($page) == false) {
-				continue;
-			}
-			$text = $func_vars['page_title'].$divider
-				.$func_vars['page_menu_title'].$divider
-				.($cfg_search_description?$func_vars['page_description']:"").$divider
-				.($cfg_search_keywords?$func_vars['page_keywords']:"").$divider;
-			$mod_vars = array(
-				'page_link' => $func_vars['page_link'],
-				'page_link_target' => "",
-				'page_title' => $func_vars['page_title'],
-				'page_description' => $func_vars['page_description'],
-				'page_modified_when' => $func_vars['page_modified_when'],
-				'page_modified_by' => $func_vars['page_modified_by'],
-				'text' => $text,
-				'max_excerpt_num' => $func_vars['default_max_excerpt']
-			);
-			if(print_excerpt2($mod_vars, $func_vars)) {
-				$pages_listed[$page['page_id']] = true;
-			}
-		}
-	}
-
-	// Now use the old method for pages not displayed by the new method above
-	// in case someone has old modules without search.php.
-
-	// Get modules
-	$table_search = TABLE_PREFIX."search";
-	$table_sections = TABLE_PREFIX."sections";
-	$get_modules = $database->query("
-		SELECT DISTINCT s.value, s.extra
-		FROM $table_search AS s INNER JOIN $table_sections AS sec
-			ON s.value = sec.module
-		WHERE s.name = 'module'
-	");
-	$modules = array();
-	if($get_modules->numRows() > 0) {
-		while($module = $get_modules->fetchRow()) {
-			$modules[] = $module; // $modules in an array of arrays
-		}
-	}
-	// sort module search-order
-	// get the modules from $search_module_order first ...
-	$sorted_modules = array();
-	$m = count($modules);
-	$search_modules = explode(',', $search_module_order);
-	foreach($search_modules AS $item) {
-		$item = trim($item);
-		for($i=0; $i < $m; $i++) {
-			if(isset($modules[$i]) && $modules[$i]['value'] == $item) {
-				$sorted_modules[] = $modules[$i];
-				unset($modules[$i]);
-				break;
-			}
-		}
-	}
-	// ... then add the rest
-	foreach($modules AS $item) {
-		$sorted_modules[] = $item;
-	}
-
-	if($cfg_enable_old_search) { // this is the old (wb <= 2.6.7) search-function
-		$search_path_SQL = str_replace(' link ', ' '.TABLE_PREFIX.'pages.link ', $search_path_SQL);
-		foreach($sorted_modules AS $module) {
-			if(isset($seen_pages[$module['value']]) && count($seen_pages[$module['value']])>0) // skip modules handled by new search-func
-				continue;
-			$query_start = '';
-			$query_body = '';
-			$query_end = '';
-			$prepared_query = '';
-			// Get module name
-			$module_name = $module['value'];
-			if(!isset($seen_pages[$module_name])) {
-				$seen_pages[$module_name]=array();
-			}
-			// skip module 'code' - it doesn't make sense to search in a code section
-			if($module_name=="code")
-				continue;
-			// Get fields to use for title, link, etc.
-			$fields = unserialize($module['extra']);
-			// Get query start
-			$get_query_start = $database->query("SELECT value FROM ".TABLE_PREFIX."search WHERE name = 'query_start' AND extra = '$module_name' LIMIT 1");
-			if($get_query_start->numRows() > 0) {
-				// Fetch query start
-				$fetch_query_start = $get_query_start->fetchRow();
-				// Prepare query start for execution by replacing {TP} with the TABLE_PREFIX
-				$query_start = str_replace('[TP]', TABLE_PREFIX, ($fetch_query_start['value']));
-			}
-			// Get query end
-			$get_query_end = $database->query("SELECT value FROM ".TABLE_PREFIX."search WHERE name = 'query_end' AND extra = '$module_name' LIMIT 1");
-			if($get_query_end->numRows() > 0) {
-				// Fetch query end
-				$fetch_query_end = $get_query_end->fetchRow();
-				// Set query end
-				$query_end = ($fetch_query_end['value']);
-			}
-			// Get query body
-			$get_query_body = $database->query("SELECT value FROM ".TABLE_PREFIX."search WHERE name = 'query_body' AND extra = '$module_name' LIMIT 1");
-			if($get_query_body->numRows() > 0) {
-				// Fetch query body
-				$fetch_query_body = $get_query_body->fetchRow();
-				// Prepare query body for execution by replacing {STRING} with the correct one
-				$query_body = str_replace(array('[TP]','[O]','[W]'), array(TABLE_PREFIX,'LIKE','%'), ($fetch_query_body['value']));
-				// Loop through query body for each string, then combine with start and end
-				$prepared_query = $query_start." ( ( ( ";
-				$count = 0;
-				foreach($search_normal_array AS $string) {
-					if($count != 0) {
-						$prepared_query .= " ) ".$logical_operator." ( ";
-					}
-					$prepared_query .= str_replace('[STRING]', $string, $query_body);
-					$count = $count+1;
-				}
-				$count=0;
-				$prepared_query .= ' ) ) OR ( ( ';
-				foreach($search_entities_array AS $string) {
-					if($count != 0) {
-						$prepared_query .= " ) ".$logical_operator." ( ";
-					}
-					$prepared_query .= str_replace('[STRING]', $string, $query_body);
-					$count = $count+1;
-				}
-				$prepared_query .= " ) ) ) ".$query_end;
-				// Execute query
-				$page_query = $database->query($prepared_query." ".$search_path_SQL." ".$search_language_SQL_t);
-				if(!$page_query) continue; // on error, skip the rest of the current loop iteration
-				// Loop through queried items
-				if($page_query->numRows() > 0) {
-					while($page = $page_query->fetchRow()) {
-						// Only show this page if it hasn't already been listed
-						if(isset($seen_pages[$module_name][$page['page_id']]) || isset($pages_listed[$page['page_id']])) {
-							continue;
-						}
-						
-						// don't list pages with visibility == none|deleted and check if user is allowed to see the page
-						$p_table = TABLE_PREFIX."pages";
-						$viewquery = $database->query("
-							SELECT visibility, viewing_groups, viewing_users
-							FROM $p_table
-							WHERE page_id='{$page['page_id']}'
-						");
-						$visibility = 'none'; $viewing_groups="" ; $viewing_users="";
-						if($viewquery->numRows() > 0) {
-							if($res = $viewquery->fetchRow()) {
-								$visibility = $res['visibility'];
-								$viewing_groups = $res['viewing_groups'];
-								$viewing_users = $res['viewing_users'];
-								if($visibility == 'deleted' || $visibility == 'none') {
-									continue;
-								}
-								if($visibility == 'private') {
-									if($admin->page_is_visible(array(
-										'page_id'=>$page[$fields['page_id']],
-										'visibility' =>$visibility,
-										'viewing_groups'=>$viewing_groups,
-										'viewing_users'=>$viewing_users
-									)) == false) {
-										continue;
-									}
-								}
-								if($admin->page_is_active(array('page_id'=>$page[$fields['page_id']]))==false) {
-									continue;
-								}
-							}
-						}
-	
-						// Get page link
-						$link = page_link($page['link']);
-						// Add search string for highlighting
-						if ($match!='exact') {
-							$sstring = implode(" ", $search_normal_array);
-							$link = $link."?searchresult=1&amp;sstring=".urlencode($sstring);
-						} else {
-							$sstring = str_replace(" ", "_",$search_normal_array[0]);
-							$link = $link."?searchresult=2&amp;sstring=".urlencode($sstring);
-						}
-						// Set vars to be replaced by values
-						if(!isset($page['description'])) { $page['description'] = ""; }
-						if(!isset($page['modified_when'])) { $page['modified_when'] = 0; }
-						if(!isset($page['modified_by'])) { $page['modified_by'] = 0; }
-						$vars = array('[LINK]', '[TITLE]', '[DESCRIPTION]', '[USERNAME]','[DISPLAY_NAME]','[DATE]','[TIME]','[TEXT_LAST_UPDATED_BY]','[TEXT_ON]','[EXCERPT]');
-						if($page['modified_when'] > 0) {
-							$date = gmdate(DATE_FORMAT, $page['modified_when']+TIMEZONE);
-							$time = gmdate(TIME_FORMAT, $page['modified_when']+TIMEZONE);
-						} else {
-							$date = $TEXT['UNKNOWN'].' '.$TEXT['DATE'];
-							$time = $TEXT['UNKNOWN'].' '.$TEXT['TIME'];
-						}
-						$excerpt="";
-						if($cfg_show_description == 0) {
-							$page['description'] = "";
-						}
-						$values = array($link, $page['page_title'], $page['description'], $users[$page['modified_by']]['username'], $users[$page['modified_by']]['display_name'], $date, $time, $TEXT['LAST_UPDATED_BY'], strtolower($TEXT['ON']), $excerpt);
-						// Show loop code with vars replaced by values
-						echo str_replace($vars, $values, ($fetch_results_loop['value']));
-						// Say that this page has been listed
-						$seen_pages[$module_name][$page['page_id']] = true;
-						$pages_listed[$page['page_id']] = true;
-					}
-				}
-			}
-		}
-	}
-
-	// Say no items found if we should
-	if(count($pages_listed) == 0) {
-		echo $search_no_results;
-	}
-} else {
-	echo $search_no_results;
-}
-
-// Show search results_footer
-echo $search_results_footer;
-// Show search footer
-echo $search_footer;
-
+<?php
+/**
+ *
+ * @category        frontend
+ * @package         search
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+// Check if search is enabled
+if(SHOW_SEARCH != true) {
+	echo $TEXT['SEARCH'].' '.$TEXT['DISABLED'];
+	return;
+}
+
+// Include the WB functions file
+require_once(WB_PATH.'/framework/functions.php');
+
+// Get search settings
+$table=TABLE_PREFIX.'search';
+$query = $database->query("SELECT value FROM $table WHERE name = 'header' LIMIT 1");
+$fetch_header = $query->fetchRow();
+$query = $database->query("SELECT value FROM $table WHERE name = 'footer' LIMIT 1");
+$fetch_footer = $query->fetchRow();
+$query = $database->query("SELECT value FROM $table WHERE name = 'results_header' LIMIT 1");
+$fetch_results_header = $query->fetchRow();
+$query = $database->query("SELECT value FROM $table WHERE name = 'results_footer' LIMIT 1");
+$fetch_results_footer = $query->fetchRow();
+$query = $database->query("SELECT value FROM $table WHERE name = 'results_loop' LIMIT 1");
+$fetch_results_loop = $query->fetchRow();
+$query = $database->query("SELECT value FROM $table WHERE name = 'no_results' LIMIT 1");
+$fetch_no_results = $query->fetchRow();
+$query = $database->query("SELECT value FROM $table WHERE name = 'module_order' LIMIT 1");
+if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value']='faqbaker,manual,wysiwyg'; }
+$search_module_order = $res['value'];
+$query = $database->query("SELECT value FROM $table WHERE name = 'max_excerpt' LIMIT 1");
+if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = '15'; }
+$search_max_excerpt = (int)($res['value']);
+if(!is_numeric($search_max_excerpt)) { $search_max_excerpt = 15; }
+$query = $database->query("SELECT value FROM $table WHERE name = 'cfg_show_description' LIMIT 1");
+if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = 'true'; }
+if($res['value'] == 'false') { $cfg_show_description = false; } else { $cfg_show_description = true; }
+$query = $database->query("SELECT value FROM $table WHERE name = 'cfg_search_description' LIMIT 1");
+if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = 'true'; }
+if($res['value'] == 'false') { $cfg_search_description = false; } else { $cfg_search_description = true; }
+$query = $database->query("SELECT value FROM $table WHERE name = 'cfg_search_keywords' LIMIT 1");
+if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = 'true'; }
+if($res['value'] == 'false') { $cfg_search_keywords = false; } else { $cfg_search_keywords = true; }
+$query = $database->query("SELECT value FROM $table WHERE name = 'cfg_enable_old_search' LIMIT 1");
+if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = 'true'; }
+if($res['value'] == 'false') { $cfg_enable_old_search = false; } else { $cfg_enable_old_search = true; }
+$query = $database->query("SELECT value FROM $table WHERE name = 'cfg_enable_flush' LIMIT 1");
+if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = 'false'; }
+if($res['value'] == 'false') { $cfg_enable_flush = false; } else { $cfg_enable_flush = true; }
+$query = $database->query("SELECT value FROM $table WHERE name = 'time_limit' LIMIT 1"); // time-limit per module
+if($query->numRows() > 0) { $res = $query->fetchRow(); } else { $res['value'] = '0'; }
+$search_time_limit = (int)($res['value']);
+if($search_time_limit < 1) $search_time_limit = 0;
+
+// search-module-extension: get helper-functions
+require_once(WB_PATH.'/search/search_modext.php');
+// search-module-extension: Get "search.php" for each module, if present
+// looks in modules/module/ and modules/module_searchext/
+$search_funcs = array();$search_funcs['__before'] = array();$search_funcs['__after'] = array();
+$query = $database->query("SELECT DISTINCT directory FROM ".TABLE_PREFIX."addons WHERE type = 'module' AND directory NOT LIKE '%_searchext'");
+if($query->numRows() > 0) {
+	while($module = $query->fetchRow()) {
+		$file = WB_PATH.'/modules/'.$module['directory'].'/search.php';
+		if(!file_exists($file)) {
+			$file = WB_PATH.'/modules/'.$module['directory'].'_searchext/search.php';
+			if(!file_exists($file)) {
+				$file='';
+			}
+		}
+		if($file!='') {
+			include_once($file);
+			if(function_exists($module['directory']."_search")) {
+				$search_funcs[$module['directory']] = $module['directory']."_search";
+			}
+			if(function_exists($module['directory']."_search_before")) {
+				$search_funcs['__before'][] = $module['directory']."_search_before";
+			}
+			if(function_exists($module['directory']."_search_after")) {
+				$search_funcs['__after'][] = $module['directory']."_search_after";
+			}
+		}
+	}
+}
+
+// Get list of usernames and display names
+$query = $database->query("SELECT user_id,username,display_name FROM ".TABLE_PREFIX."users");
+$users = array('0' => array('display_name' => $TEXT['UNKNOWN'], 'username' => strtolower($TEXT['UNKNOWN'])));
+if($query->numRows() > 0) {
+	while($user = $query->fetchRow()) {
+		$users[$user['user_id']] = array('display_name' => $user['display_name'], 'username' => $user['username']);
+	}
+}
+
+// Get search language, used for special umlaut handling (DE: ß=ss, ...)
+$search_lang = '';
+if(isset($_REQUEST['search_lang'])) {
+	$search_lang = $_REQUEST['search_lang'];
+	if(!preg_match('~^[A-Z]{2}$~', $search_lang))
+		$search_lang = LANGUAGE;
+} else {
+	$search_lang = LANGUAGE;
+}
+
+// Get the path to search into. Normally left blank
+// ATTN: since wb2.7.1 the path is evaluated as SQL: LIKE "/path%" - which will find "/path.php", "/path/info.php", ...; But not "/de/path.php"
+// Add a '%' in front of each path to get SQL: LIKE "%/path%"
+/* possible values:
+ * - a single path: "/en/" - search only pages whose link contains 'path' ("/en/machinery/bender-x09")
+ * - a single path not to search into: "-/help" - search all, exclude /help...
+ * - a bunch of alternative pathes: "/en/,%/machinery/,/docs/" - alternatives paths, seperated by comma
+ * - a bunch of paths to exclude: "-/about,%/info,/jp/,/light" - search all, exclude these.
+ * These different styles can't be mixed.
+ */
+// ATTN: in wb2.7.0 "/en/" matched all links with "/en/" somewhere in the link: "/info/en/intro.php", "/en/info.php", ...
+// since wb2.7.1 "/en/" matches only links _starting_  with "/en/": "/en/intro/info.php"
+// use "%/en/" (or "%/en/, %/info", ...) to get the old behavior
+$search_path_SQL = '';
+$search_path = '';
+if(isset($_REQUEST['search_path'])) {
+	$search_path = addslashes(htmlspecialchars(strip_tags($wb->strip_slashes($_REQUEST['search_path'])), ENT_QUOTES));
+	if(!preg_match('~^%?[-a-zA-Z0-9_,/ ]+$~', $search_path))
+		$search_path = '';
+	if($search_path != '') {
+		$search_path_SQL = 'AND ( ';
+		$not = '';
+		$op = 'OR';
+		if($search_path[0] == '-') {
+			$not = 'NOT';
+			$op = 'AND';
+			$paths = explode(',', substr($search_path, 1) );
+		} else {
+			$paths = explode(',',$search_path);
+		}
+		$i=0;
+		foreach($paths as $p) {
+			if($i++ > 0) {
+				$search_path_SQL .= ' $op';
+			}
+			$search_path_SQL .= " link $not LIKE '".$p."%'";			
+		}
+		$search_path_SQL .= ' )';
+	}
+}
+
+// use page_languages?
+if(PAGE_LANGUAGES) {
+	$table = TABLE_PREFIX."pages";
+	$search_language_SQL_t = "AND $table.`language` = '".LANGUAGE."'";
+	$search_language_SQL = "AND `language` = '".LANGUAGE."'";
+} else {
+	$search_language_SQL_t = '';
+	$search_language_SQL = '';
+}
+
+// Get the search type
+$match = '';
+if(isset($_REQUEST['match'])) {
+	if($_REQUEST['match']=='any') $match = 'any';
+	elseif($_REQUEST['match']=='all') $match = 'all';
+	elseif($_REQUEST['match']=='exact') $match = 'exact';
+	else $match = 'all';
+} else {
+	$match = 'all';
+}
+
+// Get search string
+$search_normal_string = '';
+$search_entities_string = ''; // for SQL's LIKE
+$search_display_string = ''; // for displaying
+$search_url_string = ''; // for $_GET -- ATTN: unquoted! Will become urldecoded later
+$string = '';
+if(isset($_REQUEST['string']))
+{
+	if($match!='exact') // $string will be cleaned below 
+    {
+		$string=str_replace(',', '', $_REQUEST['string']);
+	} else {
+		$string=$_REQUEST['string'];
+	}
+    // redo possible magic quotes
+    $string = $wb->strip_slashes($string);
+    $string = preg_replace('/[ \r\n\t]+/', ' ', $string);
+    $string = trim($string);
+	// remove some bad chars
+	$string = str_replace ( array('[[',']]'),'', $string);
+	$string = preg_replace('/(^|\s+)[|.]+(?=\s+|$)/', '', $string);
+	$search_display_string = htmlspecialchars($string);
+	$search_entities_string = addslashes(umlauts_to_entities(htmlspecialchars($string)));
+	// mySQL needs four backslashes to match one in LIKE comparisons)
+	$search_entities_string = str_replace('\\\\', '\\\\\\\\', $search_entities_string);
+	// convert string to utf-8
+	$string = entities_to_umlauts($string, 'UTF-8');
+	$search_url_string = $string;
+	$string = preg_quote($string);
+	// quote ' " and /  -we need quoted / for regex
+	$search_normal_string = str_replace(array('\'','"','/'), array('\\\'','\"','\/'), $string);
+}
+// make arrays from the search_..._strings above
+if($match == 'exact')
+	$search_url_array[] = $search_url_string;
+else
+	$search_url_array = explode(' ', $search_url_string);
+$search_normal_array = array();
+$search_entities_array = array();
+if($match == 'exact') {
+	$search_normal_array[]=$search_normal_string;
+	$search_entities_array[]=$search_entities_string;
+} else {
+	$exploded_string = explode(' ', $search_normal_string);
+	// Make sure there is no blank values in the array
+	foreach($exploded_string AS $each_exploded_string) {
+		if($each_exploded_string != '') {
+			$search_normal_array[] = $each_exploded_string;
+		}
+	}
+	$exploded_string = explode(' ', $search_entities_string);
+	// Make sure there is no blank values in the array
+	foreach($exploded_string AS $each_exploded_string) {
+		if($each_exploded_string != '') {
+			$search_entities_array[] = $each_exploded_string;
+		}
+	}
+}
+// make an extra copy of search_normal_array for use in regex
+require(WB_PATH.'/search/search_convert.php');
+$search_words = array();
+foreach($search_normal_array AS $str) {
+	$str = str_replace($string_ul_umlaut, $string_ul_regex, $str);
+	$search_words[] = $str;
+}
+
+// Work-out what to do (match all words, any words, or do exact match), and do relevant with query settings
+$all_checked = '';
+$any_checked = '';
+$exact_checked = '';
+if ($match == 'any') {
+	$any_checked = ' checked="checked"';
+	$logical_operator = ' OR';
+} elseif($match == 'all') {
+	$all_checked = ' checked="checked"';
+	$logical_operator = ' AND';
+} else {
+	$exact_checked = ' checked="checked"';
+}
+
+// Replace vars in search settings with values
+$vars = array('[SEARCH_STRING]', '[WB_URL]', '[PAGE_EXTENSION]', '[TEXT_RESULTS_FOR]');
+$values = array($search_display_string, WB_URL, PAGE_EXTENSION, $TEXT['RESULTS_FOR']);
+$search_footer = str_replace($vars, $values, ($fetch_footer['value']));
+$search_results_header = str_replace($vars, $values, ($fetch_results_header['value']));
+$search_results_footer = str_replace($vars, $values, ($fetch_results_footer['value']));
+
+// Do extra vars/values replacement
+$vars = array('[SEARCH_STRING]', '[WB_URL]', '[PAGE_EXTENSION]', '[TEXT_SEARCH]', '[TEXT_ALL_WORDS]', '[TEXT_ANY_WORDS]', '[TEXT_EXACT_MATCH]', '[TEXT_MATCH]', '[TEXT_MATCHING]', '[ALL_CHECKED]', '[ANY_CHECKED]', '[EXACT_CHECKED]', '[REFERRER_ID]', '[SEARCH_PATH]');
+$values = array($search_display_string, WB_URL, PAGE_EXTENSION, $TEXT['SEARCH'], $TEXT['ALL_WORDS'], $TEXT['ANY_WORDS'], $TEXT['EXACT_MATCH'], $TEXT['MATCH'], $TEXT['MATCHING'], $all_checked, $any_checked, $exact_checked, REFERRER_ID, $search_path);
+$search_header = str_replace($vars, $values, ($fetch_header['value']));
+$vars = array('[TEXT_NO_RESULTS]');
+$values = array($TEXT['NO_RESULTS']);
+$search_no_results = str_replace($vars, $values, ($fetch_no_results['value']));
+
+/*
+ * Start of output
+ */
+
+// Show search header
+echo $search_header;
+// Show search results_header
+echo $search_results_header;
+
+// Work-out if the user has already entered their details or not
+if($search_normal_string != '') {
+
+	// Get modules
+	$table = TABLE_PREFIX."sections";
+	$get_modules = $database->query("SELECT DISTINCT module FROM $table WHERE module != '' ");
+	$modules = array();
+	if($get_modules->numRows() > 0) {
+		while($module = $get_modules->fetchRow()) {
+			$modules[] = $module['module'];
+		}
+	}
+	// sort module search-order
+	// get the modules from $search_module_order first ...
+	$sorted_modules = array();
+	$m = count($modules);
+	$search_modules = explode(',', $search_module_order);
+	foreach($search_modules AS $item) {
+		$item = trim($item);
+		for($i=0; $i < $m; $i++) {
+			if(isset($modules[$i]) && $modules[$i] == $item) {
+				$sorted_modules[] = $modules[$i];
+				unset($modules[$i]);
+				break;
+			}
+		}
+	}
+	// ... then add the rest
+	foreach($modules AS $item) {
+		$sorted_modules[] = $item;
+	}
+
+
+	// Use the module's search-extensions.
+	// This is somewhat slower than the orginial method.
+	
+	// call $search_funcs['__before'] first
+	$search_func_vars = array(
+		'database' => $database, // database-handle
+		'page_id' => 0,
+		'section_id' => 0,
+		'page_title' => '',
+		'page_menu_title' => '',
+		'page_description' => '',
+		'page_keywords' => '',
+		'page_link' => '',
+		'page_modified_when' => 0,
+		'page_modified_by' => 0,
+		'users' => $users, // array of known user-id/user-name
+		'search_words' => $search_words, // array of strings, prepared for regex
+		'search_match' => $match, // match-type
+		'search_url_array' => $search_url_array, // array of strings from the original search-string. ATTN: strings are not quoted!
+		'results_loop_string' => $fetch_results_loop['value'],
+		'default_max_excerpt' => $search_max_excerpt,
+		'time_limit' => $search_time_limit, // time-limit in secs
+		'search_path' => $search_path // see docu
+	);
+	foreach($search_funcs['__before'] as $func) {
+		$uf_res = call_user_func($func, $search_func_vars);
+	}
+	// now call module-based $search_funcs[]
+	$seen_pages = array(); // seen pages per module.
+	$pages_listed = array(); // seen pages.
+	if($search_max_excerpt!=0) { // skip this search if $search_max_excerpt==0
+		foreach($sorted_modules AS $module_name) {
+			$start_time = time();	// get start-time to check time-limit; not very accurate, but ok
+			$seen_pages[$module_name] = array();
+			if(!isset($search_funcs[$module_name])) {
+				continue; // there is no search_func for this module
+			}
+			// get each section for $module_name
+			$table_s = TABLE_PREFIX."sections";	
+			$table_p = TABLE_PREFIX."pages";
+			$sections_query = $database->query("
+				SELECT s.section_id, s.page_id, s.module, s.publ_start, s.publ_end,
+							 p.page_title, p.menu_title, p.link, p.description, p.keywords, p.modified_when, p.modified_by,
+							 p.visibility, p.viewing_groups, p.viewing_users
+				FROM $table_s AS s INNER JOIN $table_p AS p ON s.page_id = p.page_id
+				WHERE s.module = '$module_name' AND p.visibility NOT IN ('none','deleted') AND p.searching = '1' $search_path_SQL $search_language_SQL
+				ORDER BY s.page_id, s.position ASC
+			");
+			if($sections_query->numRows() > 0) {
+				while($res = $sections_query->fetchRow()) {
+					// check if time-limit is exceeded for this module
+					if($search_time_limit > 0 && (time()-$start_time > $search_time_limit)) {
+						break;
+					}
+					// Only show this section if it is not "out of publication-date"
+					$now = time();
+					if( !( $now<$res['publ_end'] && ($now>$res['publ_start'] || $res['publ_start']==0) ||
+						$now>$res['publ_start'] && $res['publ_end']==0) ) {
+						continue;
+					}
+					$search_func_vars = array(
+						'database' => $database,
+						'page_id' => $res['page_id'],
+						'section_id' => $res['section_id'],
+						'page_title' => $res['page_title'],
+						'page_menu_title' => $res['menu_title'],
+						'page_description' => ($cfg_show_description?$res['description']:""),
+						'page_keywords' => $res['keywords'],
+						'page_link' => $res['link'],
+						'page_modified_when' => $res['modified_when'],
+						'page_modified_by' => $res['modified_by'],
+						'users' => $users,
+						'search_words' => $search_words, // needed for preg_match
+						'search_match' => $match,
+						'search_url_array' => $search_url_array, // needed for url-string only
+						'results_loop_string' => $fetch_results_loop['value'],
+						'default_max_excerpt' => $search_max_excerpt,
+						'enable_flush' => $cfg_enable_flush,
+						'time_limit' => $search_time_limit // time-limit in secs
+					);
+					// Only show this page if we are allowed to see it
+					if($admin->page_is_visible($res) == false) {
+						if($res['visibility'] == 'registered') { // don't show excerpt
+							$search_func_vars['default_max_excerpt'] = 0;
+							$search_func_vars['page_description'] = $TEXT['REGISTERED'];
+						} else { // private
+							continue;
+						}
+					}
+					$uf_res = call_user_func($search_funcs[$module_name], $search_func_vars);
+					if($uf_res) {
+						$pages_listed[$res['page_id']] = true;
+						$seen_pages[$module_name][$res['page_id']] = true;
+					} else {
+						$seen_pages[$module_name][$res['page_id']] = true;
+					}
+				}
+			}
+		}
+	}
+	// now call $search_funcs['__after']
+	$search_func_vars = array(
+		'database' => $database, // database-handle
+		'page_id' => 0,
+		'section_id' => 0,
+		'page_title' => '',
+		'page_menu_title' => '',
+		'page_description' => '',
+		'page_keywords' => '',
+		'page_link' => '',
+		'page_modified_when' => 0,
+		'page_modified_by' => 0,
+		'users' => $users, // array of known user-id/user-name
+		'search_words' => $search_words, // array of strings, prepared for regex
+		'search_match' => $match, // match-type
+		'search_url_array' => $search_url_array, // array of strings from the original search-string. ATTN: strings are not quoted!
+		'results_loop_string' => $fetch_results_loop['value'],
+		'default_max_excerpt' => $search_max_excerpt,
+		'time_limit' => $search_time_limit, // time-limit in secs
+		'search_path' => $search_path // see docu
+	);
+	foreach($search_funcs['__after'] as $func) {
+		$uf_res = call_user_func($func, $search_func_vars);
+	}
+
+
+	// Search page details only, such as description, keywords, etc, but only of unseen pages.
+	$max_excerpt_num = 0; // we don't want excerpt here
+	$divider = ".";
+	$table = TABLE_PREFIX."pages";
+	$query_pages = $database->query("
+		SELECT page_id, page_title, menu_title, link, description, keywords, modified_when, modified_by,
+		       visibility, viewing_groups, viewing_users
+		FROM $table
+		WHERE visibility NOT IN ('none','deleted') AND searching = '1' $search_path_SQL $search_language_SQL
+	");
+	if($query_pages->numRows() > 0) {
+		while($page = $query_pages->fetchRow()) {
+			if (isset($pages_listed[$page['page_id']])) {
+				continue;
+			}
+			$func_vars = array(
+				'database' => $database,
+				'page_id' => $page['page_id'],
+				'page_title' => $page['page_title'],
+				'page_menu_title' => $page['menu_title'],
+				'page_description' => ($cfg_show_description?$page['description']:""),
+				'page_keywords' => $page['keywords'],
+				'page_link' => $page['link'],
+				'page_modified_when' => $page['modified_when'],
+				'page_modified_by' => $page['modified_by'],
+				'users' => $users,
+				'search_words' => $search_words, // needed for preg_match_all
+				'search_match' => $match,
+				'search_url_array' => $search_url_array, // needed for url-string only
+				'results_loop_string' => $fetch_results_loop['value'],
+				'default_max_excerpt' => $max_excerpt_num,
+				'enable_flush' => $cfg_enable_flush
+			);
+			// Only show this page if we are allowed to see it
+			if($admin->page_is_visible($page) == false) {
+				if($page['visibility'] != 'registered') {
+					continue;
+				} else { // page: registered, user: access denied
+					$func_vars['page_description'] = $TEXT['REGISTERED'];
+				}
+			}
+			if($admin->page_is_active($page) == false) {
+				continue;
+			}
+			$text = $func_vars['page_title'].$divider
+				.$func_vars['page_menu_title'].$divider
+				.($cfg_search_description?$func_vars['page_description']:"").$divider
+				.($cfg_search_keywords?$func_vars['page_keywords']:"").$divider;
+			$mod_vars = array(
+				'page_link' => $func_vars['page_link'],
+				'page_link_target' => "",
+				'page_title' => $func_vars['page_title'],
+				'page_description' => $func_vars['page_description'],
+				'page_modified_when' => $func_vars['page_modified_when'],
+				'page_modified_by' => $func_vars['page_modified_by'],
+				'text' => $text,
+				'max_excerpt_num' => $func_vars['default_max_excerpt']
+			);
+			if(print_excerpt2($mod_vars, $func_vars)) {
+				$pages_listed[$page['page_id']] = true;
+			}
+		}
+	}
+
+	// Now use the old method for pages not displayed by the new method above
+	// in case someone has old modules without search.php.
+
+	// Get modules
+	$table_search = TABLE_PREFIX."search";
+	$table_sections = TABLE_PREFIX."sections";
+	$get_modules = $database->query("
+		SELECT DISTINCT s.value, s.extra
+		FROM $table_search AS s INNER JOIN $table_sections AS sec
+			ON s.value = sec.module
+		WHERE s.name = 'module'
+	");
+	$modules = array();
+	if($get_modules->numRows() > 0) {
+		while($module = $get_modules->fetchRow()) {
+			$modules[] = $module; // $modules in an array of arrays
+		}
+	}
+	// sort module search-order
+	// get the modules from $search_module_order first ...
+	$sorted_modules = array();
+	$m = count($modules);
+	$search_modules = explode(',', $search_module_order);
+	foreach($search_modules AS $item) {
+		$item = trim($item);
+		for($i=0; $i < $m; $i++) {
+			if(isset($modules[$i]) && $modules[$i]['value'] == $item) {
+				$sorted_modules[] = $modules[$i];
+				unset($modules[$i]);
+				break;
+			}
+		}
+	}
+	// ... then add the rest
+	foreach($modules AS $item) {
+		$sorted_modules[] = $item;
+	}
+
+	if($cfg_enable_old_search) { // this is the old (wb <= 2.6.7) search-function
+		$search_path_SQL = str_replace(' link ', ' '.TABLE_PREFIX.'pages.link ', $search_path_SQL);
+		foreach($sorted_modules AS $module) {
+			if(isset($seen_pages[$module['value']]) && count($seen_pages[$module['value']])>0) // skip modules handled by new search-func
+				continue;
+			$query_start = '';
+			$query_body = '';
+			$query_end = '';
+			$prepared_query = '';
+			// Get module name
+			$module_name = $module['value'];
+			if(!isset($seen_pages[$module_name])) {
+				$seen_pages[$module_name]=array();
+			}
+			// skip module 'code' - it doesn't make sense to search in a code section
+			if($module_name=="code")
+				continue;
+			// Get fields to use for title, link, etc.
+			$fields = unserialize($module['extra']);
+			// Get query start
+			$get_query_start = $database->query("SELECT value FROM ".TABLE_PREFIX."search WHERE name = 'query_start' AND extra = '$module_name' LIMIT 1");
+			if($get_query_start->numRows() > 0) {
+				// Fetch query start
+				$fetch_query_start = $get_query_start->fetchRow();
+				// Prepare query start for execution by replacing {TP} with the TABLE_PREFIX
+				$query_start = str_replace('[TP]', TABLE_PREFIX, ($fetch_query_start['value']));
+			}
+			// Get query end
+			$get_query_end = $database->query("SELECT value FROM ".TABLE_PREFIX."search WHERE name = 'query_end' AND extra = '$module_name' LIMIT 1");
+			if($get_query_end->numRows() > 0) {
+				// Fetch query end
+				$fetch_query_end = $get_query_end->fetchRow();
+				// Set query end
+				$query_end = ($fetch_query_end['value']);
+			}
+			// Get query body
+			$get_query_body = $database->query("SELECT value FROM ".TABLE_PREFIX."search WHERE name = 'query_body' AND extra = '$module_name' LIMIT 1");
+			if($get_query_body->numRows() > 0) {
+				// Fetch query body
+				$fetch_query_body = $get_query_body->fetchRow();
+				// Prepare query body for execution by replacing {STRING} with the correct one
+				$query_body = str_replace(array('[TP]','[O]','[W]'), array(TABLE_PREFIX,'LIKE','%'), ($fetch_query_body['value']));
+				// Loop through query body for each string, then combine with start and end
+				$prepared_query = $query_start." ( ( ( ";
+				$count = 0;
+				foreach($search_normal_array AS $string) {
+					if($count != 0) {
+						$prepared_query .= " ) ".$logical_operator." ( ";
+					}
+					$prepared_query .= str_replace('[STRING]', $string, $query_body);
+					$count = $count+1;
+				}
+				$count=0;
+				$prepared_query .= ' ) ) OR ( ( ';
+				foreach($search_entities_array AS $string) {
+					if($count != 0) {
+						$prepared_query .= " ) ".$logical_operator." ( ";
+					}
+					$prepared_query .= str_replace('[STRING]', $string, $query_body);
+					$count = $count+1;
+				}
+				$prepared_query .= " ) ) ) ".$query_end;
+				// Execute query
+				$page_query = $database->query($prepared_query." ".$search_path_SQL." ".$search_language_SQL_t);
+				if(!$page_query) continue; // on error, skip the rest of the current loop iteration
+				// Loop through queried items
+				if($page_query->numRows() > 0) {
+					while($page = $page_query->fetchRow()) {
+						// Only show this page if it hasn't already been listed
+						if(isset($seen_pages[$module_name][$page['page_id']]) || isset($pages_listed[$page['page_id']])) {
+							continue;
+						}
+						
+						// don't list pages with visibility == none|deleted and check if user is allowed to see the page
+						$p_table = TABLE_PREFIX."pages";
+						$viewquery = $database->query("
+							SELECT visibility, viewing_groups, viewing_users
+							FROM $p_table
+							WHERE page_id='{$page['page_id']}'
+						");
+						$visibility = 'none'; $viewing_groups="" ; $viewing_users="";
+						if($viewquery->numRows() > 0) {
+							if($res = $viewquery->fetchRow()) {
+								$visibility = $res['visibility'];
+								$viewing_groups = $res['viewing_groups'];
+								$viewing_users = $res['viewing_users'];
+								if($visibility == 'deleted' || $visibility == 'none') {
+									continue;
+								}
+								if($visibility == 'private') {
+									if($admin->page_is_visible(array(
+										'page_id'=>$page[$fields['page_id']],
+										'visibility' =>$visibility,
+										'viewing_groups'=>$viewing_groups,
+										'viewing_users'=>$viewing_users
+									)) == false) {
+										continue;
+									}
+								}
+								if($admin->page_is_active(array('page_id'=>$page[$fields['page_id']]))==false) {
+									continue;
+								}
+							}
+						}
+	
+						// Get page link
+						$link = page_link($page['link']);
+						// Add search string for highlighting
+						if ($match!='exact') {
+							$sstring = implode(" ", $search_normal_array);
+							$link = $link."?searchresult=1&amp;sstring=".urlencode($sstring);
+						} else {
+							$sstring = str_replace(" ", "_",$search_normal_array[0]);
+							$link = $link."?searchresult=2&amp;sstring=".urlencode($sstring);
+						}
+						// Set vars to be replaced by values
+						if(!isset($page['description'])) { $page['description'] = ""; }
+						if(!isset($page['modified_when'])) { $page['modified_when'] = 0; }
+						if(!isset($page['modified_by'])) { $page['modified_by'] = 0; }
+						$vars = array('[LINK]', '[TITLE]', '[DESCRIPTION]', '[USERNAME]','[DISPLAY_NAME]','[DATE]','[TIME]','[TEXT_LAST_UPDATED_BY]','[TEXT_ON]','[EXCERPT]');
+						if($page['modified_when'] > 0) {
+							$date = gmdate(DATE_FORMAT, $page['modified_when']+TIMEZONE);
+							$time = gmdate(TIME_FORMAT, $page['modified_when']+TIMEZONE);
+						} else {
+							$date = $TEXT['UNKNOWN'].' '.$TEXT['DATE'];
+							$time = $TEXT['UNKNOWN'].' '.$TEXT['TIME'];
+						}
+						$excerpt="";
+						if($cfg_show_description == 0) {
+							$page['description'] = "";
+						}
+						$values = array($link, $page['page_title'], $page['description'], $users[$page['modified_by']]['username'], $users[$page['modified_by']]['display_name'], $date, $time, $TEXT['LAST_UPDATED_BY'], strtolower($TEXT['ON']), $excerpt);
+						// Show loop code with vars replaced by values
+						echo str_replace($vars, $values, ($fetch_results_loop['value']));
+						// Say that this page has been listed
+						$seen_pages[$module_name][$page['page_id']] = true;
+						$pages_listed[$page['page_id']] = true;
+					}
+				}
+			}
+		}
+	}
+
+	// Say no items found if we should
+	if(count($pages_listed) == 0) {
+		echo $search_no_results;
+	}
+} else {
+	echo $search_no_results;
+}
+
+// Show search results_footer
+echo $search_results_footer;
+// Show search footer
+echo $search_footer;
+
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/search/search_convert.php
===================================================================
--- branches/2.8.x/wb/search/search_convert.php	(revision 1419)
+++ branches/2.8.x/wb/search/search_convert.php	(revision 1420)
@@ -1,86 +1,85 @@
-<?php
-/**
- *
- * @category        frontend
- * @package         search
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
-if(!isset($search_lang)) $search_lang = LANGUAGE;
-
-// umlaut to '(upper|lower)' for preg_match()
-// this is UTF-8-encoded
-// there is no need for a translation-table anymore since we use u-switch (utf-8) for preg-functions
-// remember that we use the i-switch, too. [No need for (ae|Ae)]
-
-$string_ul_umlaut = array();
-$string_ul_regex = array();
-
-// but add some national stuff
-if($search_lang=='DE') { // add special handling for german umlauts (ä==ae, ...)
-	$string_ul_umlaut_add = array(
-		"\xc3\x9f", // german SZ-Ligatur
-		"\xc3\xa4", // german ae
-		"\xc3\xb6", // german oe
-		"\xc3\xbc", // german ue
-		"\xc3\x84", // german Ae
-		"\xc3\x96", // german Oe
-		"\xc3\x9c", // german Ue
-		// these are not that usual
-		"\xEF\xAC\x84", // german ffl-ligatur
-		"ffl",          // german ffl-ligatur
-		"\xEF\xAC\x83", // german ffi-ligatur
-		"ffi",          // german ffi-ligatur
-		"0xEF\xAC\x80", // german ff-Ligatur
-		"ff",           // german ff-Ligatur
-		"\xEF\xAC\x81", // german fi-ligatur
-		"fi",           // german fi-ligatur
-		"\xEF\xAC\x82", // german fl-ligatur
-		"fl",           // german fl-ligatur
-		"\xEF\xAC\x85", // german st-Ligatur (long s)
-		"st",           // german st-Ligatur
-		"\xEF\xAC\x86"  // german st-ligatur (round-s)
-	);
-	$string_ul_regex_add = array(
-		"(\xc3\x9f|ss)", // german SZ.Ligatur
-		"(\xc3\xa4|ae)", // german ae
-		"(\xc3\xb6|oe)", // german oe
-		"(\xc3\xbc|ue)", // german ue
-		"(\xc3\x84|Ae)", // german Ae
-		"(\xc3\x96|Oe)", // german Oe
-		"(\xc3\x9c|Ue)", // german Ue
-		// these are not that usual
-		"(\xEF\xAC\x84|ffl)", // german ffl-ligatur
-		"(\xEF\xAC\x84|ffl)", // german ffl-ligatur
-		"(\xEF\xAC\x83|ffi)", // german ffi-ligatur
-		"(\xEF\xAC\x83|ffi)", // german ffi-ligatur
-		"(\xEF\xAC\x80|ff)",  // german ff-Ligatur
-		"(\xEF\xAC\x80|ff)",  // german ff-Ligatur
-		"(\xEF\xAC\x81|fi)",  // german fi-Ligatur
-		"(\xEF\xAC\x81|fi)",  // german fi-Ligatur
-		"(\xEF\xAC\x82|fl)",  // german fl-ligatur
-		"(\xEF\xAC\x82|fl)",  // german fl-ligatur
-		"(\xEF\xAC\x85|st)",  // german st-Ligatur (long s)
-		"(\xEF\xAC\x85|st|\xEF\xAC\x86)",  // german st-Ligaturs
-		"(\xEF\xAC\x86|st)"  // german st-ligatur (round-s)
-	);
-	$string_ul_umlaut = array_merge($string_ul_umlaut_add, $string_ul_umlaut);
-	$string_ul_regex = array_merge($string_ul_regex_add, $string_ul_regex);
-}
-
-
+<?php
+/**
+ *
+ * @category        frontend
+ * @package         search
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+if(!isset($search_lang)) $search_lang = LANGUAGE;
+
+// umlaut to '(upper|lower)' for preg_match()
+// this is UTF-8-encoded
+// there is no need for a translation-table anymore since we use u-switch (utf-8) for preg-functions
+// remember that we use the i-switch, too. [No need for (ae|Ae)]
+
+$string_ul_umlaut = array();
+$string_ul_regex = array();
+
+// but add some national stuff
+if($search_lang=='DE') { // add special handling for german umlauts (ä==ae, ...)
+	$string_ul_umlaut_add = array(
+		"\xc3\x9f", // german SZ-Ligatur
+		"\xc3\xa4", // german ae
+		"\xc3\xb6", // german oe
+		"\xc3\xbc", // german ue
+		"\xc3\x84", // german Ae
+		"\xc3\x96", // german Oe
+		"\xc3\x9c", // german Ue
+		// these are not that usual
+		"\xEF\xAC\x84", // german ffl-ligatur
+		"ffl",          // german ffl-ligatur
+		"\xEF\xAC\x83", // german ffi-ligatur
+		"ffi",          // german ffi-ligatur
+		"0xEF\xAC\x80", // german ff-Ligatur
+		"ff",           // german ff-Ligatur
+		"\xEF\xAC\x81", // german fi-ligatur
+		"fi",           // german fi-ligatur
+		"\xEF\xAC\x82", // german fl-ligatur
+		"fl",           // german fl-ligatur
+		"\xEF\xAC\x85", // german st-Ligatur (long s)
+		"st",           // german st-Ligatur
+		"\xEF\xAC\x86"  // german st-ligatur (round-s)
+	);
+	$string_ul_regex_add = array(
+		"(\xc3\x9f|ss)", // german SZ.Ligatur
+		"(\xc3\xa4|ae)", // german ae
+		"(\xc3\xb6|oe)", // german oe
+		"(\xc3\xbc|ue)", // german ue
+		"(\xc3\x84|Ae)", // german Ae
+		"(\xc3\x96|Oe)", // german Oe
+		"(\xc3\x9c|Ue)", // german Ue
+		// these are not that usual
+		"(\xEF\xAC\x84|ffl)", // german ffl-ligatur
+		"(\xEF\xAC\x84|ffl)", // german ffl-ligatur
+		"(\xEF\xAC\x83|ffi)", // german ffi-ligatur
+		"(\xEF\xAC\x83|ffi)", // german ffi-ligatur
+		"(\xEF\xAC\x80|ff)",  // german ff-Ligatur
+		"(\xEF\xAC\x80|ff)",  // german ff-Ligatur
+		"(\xEF\xAC\x81|fi)",  // german fi-Ligatur
+		"(\xEF\xAC\x81|fi)",  // german fi-Ligatur
+		"(\xEF\xAC\x82|fl)",  // german fl-ligatur
+		"(\xEF\xAC\x82|fl)",  // german fl-ligatur
+		"(\xEF\xAC\x85|st)",  // german st-Ligatur (long s)
+		"(\xEF\xAC\x85|st|\xEF\xAC\x86)",  // german st-Ligaturs
+		"(\xEF\xAC\x86|st)"  // german st-ligatur (round-s)
+	);
+	$string_ul_umlaut = array_merge($string_ul_umlaut_add, $string_ul_umlaut);
+	$string_ul_regex = array_merge($string_ul_regex_add, $string_ul_regex);
+}
+
+
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/search/search_modext.php
===================================================================
--- branches/2.8.x/wb/search/search_modext.php	(revision 1419)
+++ branches/2.8.x/wb/search/search_modext.php	(revision 1420)
@@ -1,449 +1,452 @@
-<?php
-/**
- *
- * @category        frontend
- * @package         search
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// make the url-string for highlighting
-function make_url_searchstring($search_match, $search_url_array)
-{
-	$link = "";
-	if ($search_match != 'exact')
-    {
-		$str = implode(" ", $search_url_array);
-		$link = "?searchresult=1&amp;sstring=".urlencode($str);
-	} else {
-		$str = str_replace(' ', '_', $search_url_array[0]);
-		$link = "?searchresult=2&amp;sstring=".urlencode($str);
-	}
-	return $link;
-}
-
-// make date and time for "last modified by... on ..."-string
-function get_page_modified($page_modified_when)
-{
-	global $TEXT;
-	if($page_modified_when > 0)
-    {
-		$date = gmdate(DATE_FORMAT, $page_modified_when+TIMEZONE);
-		$time = gmdate(TIME_FORMAT, $page_modified_when+TIMEZONE);
-	} else {
-		$date = $TEXT['UNKNOWN'].' '.$TEXT['DATE'];
-		$time = $TEXT['UNKNOWN'].' '.$TEXT['TIME'];
-	}
-	return array($date, $time);
-}
-
-// make username and displayname for "last modified by... on ..."-string
-function get_page_modified_by($page_modified_by, $users)
-{
-	global $TEXT;
-	// check for existing user-id
-	if(!isset($users[$page_modified_by]))
-    {
-        $page_modified_by = 0;
-    }
-
-	$username = $users[$page_modified_by]['username'];
-	$displayname = $users[$page_modified_by]['display_name'];
-	return array($username, $displayname);
-}
-
-// checks if _all_ searchwords matches
-function is_all_matched($text, $search_words)
-{
-	$all_matched = true;
-	foreach ($search_words AS $word)
-    {
-		if(!preg_match('/'.$word.'/ui', $text))
-        {
-			$all_matched = false;
-			break;
-		}
-	}
-	return $all_matched;
-}
-
-// checks if _any_ of the searchwords matches
-function is_any_matched($text, $search_words)
-{
-	$any_matched = false;
-	$word = '('.implode('|', $search_words).')';
-	if(preg_match('/'.$word.'/ui', $text))
-    {
-		$any_matched = true;
-	}
-	return $any_matched;
-}
-
-// collects the matches from text in excerpt_array
-function get_excerpts($text, $search_words, $max_excerpt_num)
-{
-	$match_array = array();
-	$excerpt_array = array();
-	$word = '('.implode('|', $search_words).')';
-
-	//Filter droplets from the page data
-	preg_match_all('~\[\[(.*?)\]\]~', $text, $matches);
-	foreach ($matches[1] as $match)
-    {
-		$text = str_replace('[['.$match.']]', '', $text);					
-	}
-
-	// Build the regex-string
-	if(strpos(strtoupper(PHP_OS), 'WIN')===0)  // windows -> see below
-    {
-		$str1=".!?;";
-		$str2=".!?;";
-	} else { // linux & Co.
-		// start-sign: .!?; + INVERTED EXCLAMATION MARK - INVERTED QUESTION MARK - DOUBLE EXCLAMATION MARK - INTERROBANG - EXCLAMATION QUESTION MARK - QUESTION EXCLAMATION MARK - DOUBLE QUESTION MARK - HALFWIDTH IDEOGRAPHIC FULL STOP - IDEOGRAPHIC FULL STOP - IDEOGRAPHIC COMMA
-		$str1=".!?;"."\xC2\xA1"."\xC2\xBF"."\xE2\x80\xBC"."\xE2\x80\xBD"."\xE2\x81\x89"."\xE2\x81\x88"."\xE2\x81\x87"."\xEF\xBD\xA1"."\xE3\x80\x82"."\xE3\x80\x81";
-		// stop-sign: .!?; + DOUBLE EXCLAMATION MARK - INTERROBANG - EXCLAMATION QUESTION MARK - QUESTION EXCLAMATION MARK - DOUBLE QUESTION MARK - HALFWIDTH IDEOGRAPHIC FULL STOP - IDEOGRAPHIC FULL STOP - IDEOGRAPHIC COMMA
-		$str2=".!?;"."\xE2\x80\xBC"."\xE2\x80\xBD"."\xE2\x81\x89"."\xE2\x81\x88"."\xE2\x81\x87"."\xEF\xBD\xA1"."\xE3\x80\x82"."\xE3\x80\x81";
-	}
-	$regex='/(?:^|\b|['.$str1.'])([^'.$str1.']{0,200}?'.$word.'[^'.$str2.']{0,200}(?:['.$str2.']|\b|$))/uis';
-	if(version_compare(PHP_VERSION, '4.3.3', '>=') &&
-	   strpos(strtoupper(PHP_OS), 'WIN')!==0
-	) { // this may crash windows server, so skip if on windows
-		// jump from match to match, get excerpt, stop if $max_excerpt_num is reached
-		$last_end = 0; $offset = 0;
-		while(preg_match('/'.$word.'/uis', $text, $match_array, PREG_OFFSET_CAPTURE, $last_end))
-        {
-			$offset = ($match_array[0][1]-206 < $last_end)?$last_end:$match_array[0][1]-206;
-			if(preg_match($regex, $text, $matches, PREG_OFFSET_CAPTURE, $offset))
-            {
-				$last_end = $matches[1][1]+strlen($matches[1][0])-1;
-				if(!preg_match('/\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\./', $matches[1][0])) // skip excerpts with email-addresses
-				{
-				  $excerpt_array[] = trim($matches[1][0]);
-                }
-				if(count($excerpt_array)>=$max_excerpt_num)
-                {
-					$excerpt_array = array_unique($excerpt_array);
-					if(count($excerpt_array) >= $max_excerpt_num) { break; }
-				}
-			} else { // problem: preg_match failed - can't find a start- or stop-sign
-				$last_end += 201; // jump forward and try again
-			}
-		}
-	} else { // compatible, but may be very slow with large pages
-		if(preg_match_all($regex, $text, $match_array))
-        {
-			foreach($match_array[1] AS $string)
-            {
-				if(!preg_match('/\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\./', $string))  // skip excerpts with email-addresses
-				{
-				  $excerpt_array[] = trim($string);
-                }
-
-			}
-		}
-	}
-	return $excerpt_array;
-}
-
-// makes excerpt_array a string ready to print out
-function prepare_excerpts($excerpt_array, $search_words, $max_excerpt_num)
-{
-	// excerpts: text before and after a single excerpt, html-tag for markup
-	$EXCERPT_BEFORE =       '...&nbsp;';
-	$EXCERPT_AFTER =        '&nbsp;...<br />';
-	$EXCERPT_MARKUP_START = '<b>';
-	$EXCERPT_MARKUP_END =   '</b>';
-	// remove duplicate matches from $excerpt_array, if any.
-	$excerpt_array = array_unique($excerpt_array);
-	// use the first $max_excerpt_num excerpts only
-	if(count($excerpt_array) > $max_excerpt_num)
-    {
-		$excerpt_array = array_slice($excerpt_array, 0, $max_excerpt_num);
-	}
-	// prepare search-string
-	$string = "(".implode("|", $search_words).")";
-	// we want markup on search-results page,
-	// but we need some 'magic' to prevent <br />, <b>... from being highlighted
-	$excerpt = '';
-	foreach($excerpt_array as $str)
-    {
-		$excerpt .= '#,,#'.preg_replace("/($string)/iu","#,,,,#$1#,,,,,#",$str).'#,,,#';
-	}
-	$excerpt = str_replace(array('&','<','>','"','\'',"\xC2\xA0"), array('&amp;','&lt;','&gt;','&quot;','&#039;','&nbsp;'), $excerpt);
-	$excerpt = str_replace(array('#,,,,#','#,,,,,#'), array($EXCERPT_MARKUP_START,$EXCERPT_MARKUP_END), $excerpt);
-	$excerpt = str_replace(array('#,,#','#,,,#'), array($EXCERPT_BEFORE,$EXCERPT_AFTER), $excerpt);
-	// prepare to write out
-	if(DEFAULT_CHARSET != 'utf-8')
-    {
-		$excerpt = umlauts_to_entities($excerpt, 'UTF-8');
-	}
-	return $excerpt;
-}
-
-// work out what the link-anchor should be
-function make_url_target($page_link_target, $text, $search_words)
-{
-	// 1. e.g. $page_link_target=="&monthno=5&year=2007" - module-dependent target. Do nothing.
-	// 2. $page_link_target=="#!wb_section_..." - the user wants the section-target, so do nothing.
-	// 3. $page_link_target=="#wb_section_..." - try to find a better target, use the section-target as fallback.
-	// 4. $page_link_target=="" - do nothing
-	if(version_compare(PHP_VERSION, '4.3.3', ">=") && substr($page_link_target,0,12)=='#wb_section_')
-    {
-		$word = '('.implode('|', $search_words).')';
-		preg_match('/'.$word.'/ui', $text, $match, PREG_OFFSET_CAPTURE);
-		if($match && is_array($match[0]))
-        {
-			$x=$match[0][1]; // position of first match
-			// is there an anchor nearby?
-			if(preg_match_all('/<(?:[^>]+id|\s*a[^>]+name)\s*=\s*"(.*)"/iU', substr($text,0,$x), $match, PREG_OFFSET_CAPTURE))
-            {
-				$anchor='';
-				foreach($match[1] AS $array)
-                {
-					if($array[1] > $x)
-                    {
-						break;
-					}
-					$anchor = $array[0];
-				}
-				if($anchor != '')
-                {
-					$page_link_target = '#'.$anchor;
-				}
-			}
-		}
-	} elseif(substr($page_link_target,0,13)=='#!wb_section_') {
-		$page_link_target = '#'.substr($page_link_target, 2);
-	}
-	
-	// since wb 2.7.1 the section-anchor is configurable - SEC_ANCHOR holds the anchor name
-	if(substr($page_link_target,0,12)=='#wb_section_')
-    {
-		if(defined('SEC_ANCHOR') && SEC_ANCHOR!='')
-        {
-			$sec_id = substr($page_link_target, 12);
-			$page_link_target = '#'.SEC_ANCHOR.$sec_id;
-		} else { // section-anchors are disabled
-			$page_link_target = '';
-		}
-	}
-	
-	return $page_link_target;
-}
-
-// wrapper for compatibility with old print_excerpt()
-function print_excerpt($page_link, $page_link_target, $page_title, $page_description, $page_modified_when, $page_modified_by, $text, $max_excerpt_num, $func_vars, $pic_link="")
-{
-	$mod_vars = array(
-		'page_link' => $page_link,
-		'page_link_target' => $page_link_target,
-		'page_title' => $page_title,
-		'page_description' => $page_description,
-		'page_modified_when' => $page_modified_when,
-		'page_modified_by' => $page_modified_by,
-		'text' => $text,
-		'max_excerpt_num' => $max_excerpt_num,
-		'pic_link' => $pic_link
-	);
-	print_excerpt2($mod_vars, $func_vars);
-}
-
-/* These functions can be used in module-supplied search_funcs
- * -----------------------------------------------------------
- * print_excerpt2() - the main-function to use in all search_funcs
- * print_excerpt() - wrapper for compatibility-reason. Use print_excerpt2() instead.
- * list_files_dirs() - lists all files and dirs below a given directory
- * clear_filelist() - keeps only wanted or removes unwanted entries in file-list.
- */
-
-// prints the excerpts for one section
-function print_excerpt2($mod_vars, $func_vars)
-{
-	extract($func_vars, EXTR_PREFIX_ALL, 'func');
-	extract($mod_vars, EXTR_PREFIX_ALL, 'mod');
-	global $TEXT;
-	// check $mod_...vars
-	if(!isset($mod_page_link))          { $mod_page_link = $func_page_link; }
-	if(!isset($mod_page_link_target))   { $mod_page_link_target = ''; }
-	if(!isset($mod_page_title))         { $mod_page_title = $func_page_title; }
-	if(!isset($mod_page_description))   { $mod_page_description = $func_page_description; }
-	if(!isset($mod_page_modified_when)) { $mod_page_modified_when = $func_page_modified_when; }
-	if(!isset($mod_page_modified_by))   { $mod_page_modified_by = $func_page_modified_by; }
-	if(!isset($mod_text))               { $mod_text = ''; }
-	if(!isset($mod_max_excerpt_num))    { $mod_max_excerpt_num = $func_default_max_excerpt; }
-	if(!isset($mod_pic_link))           { $mod_pic_link = ''; }
-	if(!isset($mod_no_highlight))       { $mod_no_highlight = false; }
-	if(!isset($func_enable_flush))      { $func_enable_flush = false; } // set this in db: wb_search.cfg_enable_flush [READ THE DOC BEFORE]
-	if(isset($mod_ext_charset))
-    {
-      $mod_ext_charset = strtolower($mod_ext_charset);
-    } else {
-      $mod_ext_charset = '';
-    }
-
-	if($mod_text == "") // nothing to do
-		{ return false; }
-
-	if($mod_no_highlight) // no highlighting
-		{ $mod_page_link_target = "&amp;nohighlight=1".$mod_page_link_target; }
-	// clean the text:
-	$mod_text = preg_replace('#<(!--.*--|style.*</style|script.*</script)>#iU', ' ', $mod_text);
-	$mod_text = preg_replace('#<(br( /)?|dt|/dd|/?(h[1-6]|tr|table|p|li|ul|pre|code|div|hr))[^>]*>#i', '.', $mod_text);
-	// $mod_text = preg_replace('/(\v\s?|\s\s)+/', ' ', $mod_text);
-	$mod_text = preg_replace('/\s\./', '.', $mod_text);
-	if($mod_ext_charset!='') { // data from external database may have a different charset
-		require_once(WB_PATH.'/framework/functions-utf8.php');
-		switch($mod_ext_charset) {
-		case 'latin1':
-		case 'cp1252':
-			$mod_text = charset_to_utf8($mod_text, 'CP1252');
-			break;
-		case 'cp1251':
-			$mod_text = charset_to_utf8($mod_text, 'CP1251');
-			break;
-		case 'latin2':
-			$mod_text = charset_to_utf8($mod_text, 'ISO-8859-2');
-			break;
-		case 'hebrew':
-			$mod_text = charset_to_utf8($mod_text, 'ISO-8859-8');
-			break;
-		case 'greek':
-			$mod_text = charset_to_utf8($mod_text, 'ISO-8859-7');
-			break;
-		case 'latin5':
-			$mod_text = charset_to_utf8($mod_text, 'ISO-8859-9');
-			break;
-		case 'latin7':
-			$mod_text = charset_to_utf8($mod_text, 'ISO-8859-13');
-			break;
-		case 'utf8':
-		default:
-			$mod_text = charset_to_utf8($mod_text, 'UTF-8');
-		}
-	} else {
-	$mod_text = entities_to_umlauts($mod_text, 'UTF-8');
-	}
-	$anchor_text = $mod_text; // make an copy containing html-tags
-	$mod_text = strip_tags($mod_text);
-	$mod_text = str_replace(array('&gt;','&lt;','&amp;','&quot;','&#039;','&apos;','&nbsp;'), array('>','<','&','"','\'','\'',"\xC2\xA0"), $mod_text);
-	$mod_text = '.'.trim($mod_text).'.';
-	// Do a fast scan over $mod_text first. This will speedup things a lot.
-	if($func_search_match == 'all') {
-		if(!is_all_matched($mod_text, $func_search_words))
-			return false;
-	}
-	elseif(!is_any_matched($mod_text, $func_search_words)) {
-		return false;
-	}
-	// search for an better anchor - this have to be done before strip_tags() (may fail if search-string contains <, &, amp, gt, lt, ...)
-	$anchor =  make_url_target($mod_page_link_target, $anchor_text, $func_search_words);
-
-	// make the link from $mod_page_link, add anchor
-	$link = "";
-	$link = page_link($mod_page_link);
-	if(strpos($mod_page_link, 'http:')===FALSE)
-		$link .= make_url_searchstring($func_search_match, $func_search_url_array);
-	$link .= $anchor;
-
-	// now get the excerpt
-	$excerpt = "";
-	$excerpt_array = array();
-	if($mod_max_excerpt_num > 0) {
-		if(!$excerpt_array = get_excerpts($mod_text, $func_search_words, $mod_max_excerpt_num)) {
-			return false;
-		}
-		$excerpt = prepare_excerpts($excerpt_array, $func_search_words, $mod_max_excerpt_num);
-	}
-
-	// handle thumbs - to deactivate this look in the module's search.php: $show_thumb (or maybe in the module's settings-page)
-	if($mod_pic_link != "") {
-		$excerpt = '<table class="excerpt_thumb" width="100%" cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="110" valign="top"><a href="'.$link.'"><img src="'.WB_URL.'/'.MEDIA_DIRECTORY.$mod_pic_link.'" alt="" /></a></td><td>'.$excerpt.'</td></tr></tbody></table>';
-	}
-
-	// print-out the excerpt
-	$vars = array();
-	$values = array();
-	list($date, $time) = get_page_modified($mod_page_modified_when);
-	list($username, $displayname) = get_page_modified_by($mod_page_modified_by, $func_users);
-	$vars = array('[LINK]', '[TITLE]', '[DESCRIPTION]', '[USERNAME]','[DISPLAY_NAME]','[DATE]','[TIME]','[TEXT_LAST_UPDATED_BY]','[TEXT_ON]','[EXCERPT]');
-	$values = array(
-		$link,
-		$mod_page_title,
-		$mod_page_description,
-		$username,
-		$displayname,
-		$date,
-		$time,
-		$TEXT['LAST_UPDATED_BY'],
-		$TEXT['ON'],
-		$excerpt
-	);
-	echo str_replace($vars, $values, $func_results_loop_string);
-	if($func_enable_flush) { // ATTN: this will bypass output-filters and may break template-layout or -filters
-		ob_flush();flush();
-	}
-	return true;
-}
-
-// list all files and dirs in $dir (recursive), omits '.', '..', and hidden files/dirs
-// returns an array of two arrays ($files[] and $dirs[]).
-// usage: list($files,$dirs) = list_files_dirs($directory);
-//        $depth: get subdirs (true/false)
-function list_files_dirs($dir, $depth=true, $files=array(), $dirs=array()) {
-	$dh=opendir($dir);
-	while(($file = readdir($dh)) !== false) {
-		if($file{0} == '.' || $file == '..') {
-			continue;
-		}
-		if(is_dir($dir.'/'.$file)) {
-			if($depth) {
-				$dirs[] = $dir.'/'.$file;
-				list($files, $dirs) = list_files_dirs($dir.'/'.$file, $depth, $files, $dirs);
-			}
-		} else {
-			$files[] = $dir.'/'.$file;
-		}
-	}
-	closedir($dh);
-	natcasesort($files);
-	natcasesort($dirs);
-	return(array($files, $dirs));
-}
-
-// keeps only wanted entries in array $files. $str have to be an eregi()-compatible regex
-/*
-function clear_filelist($files, $str, $keep=true)
-{
-	// options: $keep = true  : remove all non-matching entries
-	//          $keep = false : remove all matching entries
-	$c_filelist = array();
-	if($str == '')
-		return $files;
-	foreach($files as $file)
-    {
-		if($keep)
-        {
-			if(eregi($str, $file))
-            {
-				$c_filelist[] = $file;
-			}
-		} else {
-			if(!eregi($str, $file))
-            {
-				$c_filelist[] = $file;
-			}
-		}
-	}
-	return($c_filelist);
-}
-*/
+<?php
+/**
+ *
+ * @category        frontend
+ * @package         search
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+// make the url-string for highlighting
+function make_url_searchstring($search_match, $search_url_array)
+{
+	$link = "";
+	if ($search_match != 'exact')
+    {
+		$str = implode(" ", $search_url_array);
+		$link = "?searchresult=1&amp;sstring=".urlencode($str);
+	} else {
+		$str = str_replace(' ', '_', $search_url_array[0]);
+		$link = "?searchresult=2&amp;sstring=".urlencode($str);
+	}
+	return $link;
+}
+
+// make date and time for "last modified by... on ..."-string
+function get_page_modified($page_modified_when)
+{
+	global $TEXT;
+	if($page_modified_when > 0)
+    {
+		$date = gmdate(DATE_FORMAT, $page_modified_when+TIMEZONE);
+		$time = gmdate(TIME_FORMAT, $page_modified_when+TIMEZONE);
+	} else {
+		$date = $TEXT['UNKNOWN'].' '.$TEXT['DATE'];
+		$time = $TEXT['UNKNOWN'].' '.$TEXT['TIME'];
+	}
+	return array($date, $time);
+}
+
+// make username and displayname for "last modified by... on ..."-string
+function get_page_modified_by($page_modified_by, $users)
+{
+	global $TEXT;
+	// check for existing user-id
+	if(!isset($users[$page_modified_by]))
+    {
+        $page_modified_by = 0;
+    }
+
+	$username = $users[$page_modified_by]['username'];
+	$displayname = $users[$page_modified_by]['display_name'];
+	return array($username, $displayname);
+}
+
+// checks if _all_ searchwords matches
+function is_all_matched($text, $search_words)
+{
+	$all_matched = true;
+	foreach ($search_words AS $word)
+    {
+		if(!preg_match('/'.$word.'/ui', $text))
+        {
+			$all_matched = false;
+			break;
+		}
+	}
+	return $all_matched;
+}
+
+// checks if _any_ of the searchwords matches
+function is_any_matched($text, $search_words)
+{
+	$any_matched = false;
+	$word = '('.implode('|', $search_words).')';
+	if(preg_match('/'.$word.'/ui', $text))
+    {
+		$any_matched = true;
+	}
+	return $any_matched;
+}
+
+// collects the matches from text in excerpt_array
+function get_excerpts($text, $search_words, $max_excerpt_num)
+{
+	$match_array = array();
+	$excerpt_array = array();
+	$word = '('.implode('|', $search_words).')';
+
+	//Filter droplets from the page data
+	preg_match_all('~\[\[(.*?)\]\]~', $text, $matches);
+	foreach ($matches[1] as $match)
+    {
+		$text = str_replace('[['.$match.']]', '', $text);					
+	}
+
+	// Build the regex-string
+	if(strpos(strtoupper(PHP_OS), 'WIN')===0)  // windows -> see below
+    {
+		$str1=".!?;";
+		$str2=".!?;";
+	} else { // linux & Co.
+		// start-sign: .!?; + INVERTED EXCLAMATION MARK - INVERTED QUESTION MARK - DOUBLE EXCLAMATION MARK - INTERROBANG - EXCLAMATION QUESTION MARK - QUESTION EXCLAMATION MARK - DOUBLE QUESTION MARK - HALFWIDTH IDEOGRAPHIC FULL STOP - IDEOGRAPHIC FULL STOP - IDEOGRAPHIC COMMA
+		$str1=".!?;"."\xC2\xA1"."\xC2\xBF"."\xE2\x80\xBC"."\xE2\x80\xBD"."\xE2\x81\x89"."\xE2\x81\x88"."\xE2\x81\x87"."\xEF\xBD\xA1"."\xE3\x80\x82"."\xE3\x80\x81";
+		// stop-sign: .!?; + DOUBLE EXCLAMATION MARK - INTERROBANG - EXCLAMATION QUESTION MARK - QUESTION EXCLAMATION MARK - DOUBLE QUESTION MARK - HALFWIDTH IDEOGRAPHIC FULL STOP - IDEOGRAPHIC FULL STOP - IDEOGRAPHIC COMMA
+		$str2=".!?;"."\xE2\x80\xBC"."\xE2\x80\xBD"."\xE2\x81\x89"."\xE2\x81\x88"."\xE2\x81\x87"."\xEF\xBD\xA1"."\xE3\x80\x82"."\xE3\x80\x81";
+	}
+	$regex='/(?:^|\b|['.$str1.'])([^'.$str1.']{0,200}?'.$word.'[^'.$str2.']{0,200}(?:['.$str2.']|\b|$))/uis';
+	if(version_compare(PHP_VERSION, '4.3.3', '>=') &&
+	   strpos(strtoupper(PHP_OS), 'WIN')!==0
+	) { // this may crash windows server, so skip if on windows
+		// jump from match to match, get excerpt, stop if $max_excerpt_num is reached
+		$last_end = 0; $offset = 0;
+		while(preg_match('/'.$word.'/uis', $text, $match_array, PREG_OFFSET_CAPTURE, $last_end))
+        {
+			$offset = ($match_array[0][1]-206 < $last_end)?$last_end:$match_array[0][1]-206;
+			if(preg_match($regex, $text, $matches, PREG_OFFSET_CAPTURE, $offset))
+            {
+				$last_end = $matches[1][1]+strlen($matches[1][0])-1;
+				if(!preg_match('/\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\./', $matches[1][0])) // skip excerpts with email-addresses
+				{
+				  $excerpt_array[] = trim($matches[1][0]);
+                }
+				if(count($excerpt_array)>=$max_excerpt_num)
+                {
+					$excerpt_array = array_unique($excerpt_array);
+					if(count($excerpt_array) >= $max_excerpt_num) { break; }
+				}
+			} else { // problem: preg_match failed - can't find a start- or stop-sign
+				$last_end += 201; // jump forward and try again
+			}
+		}
+	} else { // compatible, but may be very slow with large pages
+		if(preg_match_all($regex, $text, $match_array))
+        {
+			foreach($match_array[1] AS $string)
+            {
+				if(!preg_match('/\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\./', $string))  // skip excerpts with email-addresses
+				{
+				  $excerpt_array[] = trim($string);
+                }
+
+			}
+		}
+	}
+	return $excerpt_array;
+}
+
+// makes excerpt_array a string ready to print out
+function prepare_excerpts($excerpt_array, $search_words, $max_excerpt_num)
+{
+	// excerpts: text before and after a single excerpt, html-tag for markup
+	$EXCERPT_BEFORE =       '...&nbsp;';
+	$EXCERPT_AFTER =        '&nbsp;...<br />';
+	$EXCERPT_MARKUP_START = '<b>';
+	$EXCERPT_MARKUP_END =   '</b>';
+	// remove duplicate matches from $excerpt_array, if any.
+	$excerpt_array = array_unique($excerpt_array);
+	// use the first $max_excerpt_num excerpts only
+	if(count($excerpt_array) > $max_excerpt_num)
+    {
+		$excerpt_array = array_slice($excerpt_array, 0, $max_excerpt_num);
+	}
+	// prepare search-string
+	$string = "(".implode("|", $search_words).")";
+	// we want markup on search-results page,
+	// but we need some 'magic' to prevent <br />, <b>... from being highlighted
+	$excerpt = '';
+	foreach($excerpt_array as $str)
+    {
+		$excerpt .= '#,,#'.preg_replace("/($string)/iu","#,,,,#$1#,,,,,#",$str).'#,,,#';
+	}
+	$excerpt = str_replace(array('&','<','>','"','\'',"\xC2\xA0"), array('&amp;','&lt;','&gt;','&quot;','&#039;','&nbsp;'), $excerpt);
+	$excerpt = str_replace(array('#,,,,#','#,,,,,#'), array($EXCERPT_MARKUP_START,$EXCERPT_MARKUP_END), $excerpt);
+	$excerpt = str_replace(array('#,,#','#,,,#'), array($EXCERPT_BEFORE,$EXCERPT_AFTER), $excerpt);
+	// prepare to write out
+	if(DEFAULT_CHARSET != 'utf-8')
+    {
+		$excerpt = umlauts_to_entities($excerpt, 'UTF-8');
+	}
+	return $excerpt;
+}
+
+// work out what the link-anchor should be
+function make_url_target($page_link_target, $text, $search_words)
+{
+	// 1. e.g. $page_link_target=="&monthno=5&year=2007" - module-dependent target. Do nothing.
+	// 2. $page_link_target=="#!wb_section_..." - the user wants the section-target, so do nothing.
+	// 3. $page_link_target=="#wb_section_..." - try to find a better target, use the section-target as fallback.
+	// 4. $page_link_target=="" - do nothing
+	if(version_compare(PHP_VERSION, '4.3.3', ">=") && substr($page_link_target,0,12)=='#wb_section_')
+    {
+		$word = '('.implode('|', $search_words).')';
+		preg_match('/'.$word.'/ui', $text, $match, PREG_OFFSET_CAPTURE);
+		if($match && is_array($match[0]))
+        {
+			$x=$match[0][1]; // position of first match
+			// is there an anchor nearby?
+			if(preg_match_all('/<(?:[^>]+id|\s*a[^>]+name)\s*=\s*"(.*)"/iU', substr($text,0,$x), $match, PREG_OFFSET_CAPTURE))
+            {
+				$anchor='';
+				foreach($match[1] AS $array)
+                {
+					if($array[1] > $x)
+                    {
+						break;
+					}
+					$anchor = $array[0];
+				}
+				if($anchor != '')
+                {
+					$page_link_target = '#'.$anchor;
+				}
+			}
+		}
+	} elseif(substr($page_link_target,0,13)=='#!wb_section_') {
+		$page_link_target = '#'.substr($page_link_target, 2);
+	}
+	
+	// since wb 2.7.1 the section-anchor is configurable - SEC_ANCHOR holds the anchor name
+	if(substr($page_link_target,0,12)=='#wb_section_')
+    {
+		if(defined('SEC_ANCHOR') && SEC_ANCHOR!='')
+        {
+			$sec_id = substr($page_link_target, 12);
+			$page_link_target = '#'.SEC_ANCHOR.$sec_id;
+		} else { // section-anchors are disabled
+			$page_link_target = '';
+		}
+	}
+	
+	return $page_link_target;
+}
+
+// wrapper for compatibility with old print_excerpt()
+function print_excerpt($page_link, $page_link_target, $page_title, $page_description, $page_modified_when, $page_modified_by, $text, $max_excerpt_num, $func_vars, $pic_link="")
+{
+	$mod_vars = array(
+		'page_link' => $page_link,
+		'page_link_target' => $page_link_target,
+		'page_title' => $page_title,
+		'page_description' => $page_description,
+		'page_modified_when' => $page_modified_when,
+		'page_modified_by' => $page_modified_by,
+		'text' => $text,
+		'max_excerpt_num' => $max_excerpt_num,
+		'pic_link' => $pic_link
+	);
+	print_excerpt2($mod_vars, $func_vars);
+}
+
+/* These functions can be used in module-supplied search_funcs
+ * -----------------------------------------------------------
+ * print_excerpt2() - the main-function to use in all search_funcs
+ * print_excerpt() - wrapper for compatibility-reason. Use print_excerpt2() instead.
+ * list_files_dirs() - lists all files and dirs below a given directory
+ * clear_filelist() - keeps only wanted or removes unwanted entries in file-list.
+ */
+
+// prints the excerpts for one section
+function print_excerpt2($mod_vars, $func_vars)
+{
+	extract($func_vars, EXTR_PREFIX_ALL, 'func');
+	extract($mod_vars, EXTR_PREFIX_ALL, 'mod');
+	global $TEXT;
+	// check $mod_...vars
+	if(!isset($mod_page_link))          { $mod_page_link = $func_page_link; }
+	if(!isset($mod_page_link_target))   { $mod_page_link_target = ''; }
+	if(!isset($mod_page_title))         { $mod_page_title = $func_page_title; }
+	if(!isset($mod_page_description))   { $mod_page_description = $func_page_description; }
+	if(!isset($mod_page_modified_when)) { $mod_page_modified_when = $func_page_modified_when; }
+	if(!isset($mod_page_modified_by))   { $mod_page_modified_by = $func_page_modified_by; }
+	if(!isset($mod_text))               { $mod_text = ''; }
+	if(!isset($mod_max_excerpt_num))    { $mod_max_excerpt_num = $func_default_max_excerpt; }
+	if(!isset($mod_pic_link))           { $mod_pic_link = ''; }
+	if(!isset($mod_no_highlight))       { $mod_no_highlight = false; }
+	if(!isset($func_enable_flush))      { $func_enable_flush = false; } // set this in db: wb_search.cfg_enable_flush [READ THE DOC BEFORE]
+	if(isset($mod_ext_charset))
+    {
+      $mod_ext_charset = strtolower($mod_ext_charset);
+    } else {
+      $mod_ext_charset = '';
+    }
+
+	if($mod_text == "") // nothing to do
+		{ return false; }
+
+	if($mod_no_highlight) // no highlighting
+		{ $mod_page_link_target = "&amp;nohighlight=1".$mod_page_link_target; }
+	// clean the text:
+	$mod_text = preg_replace('#<(!--.*--|style.*</style|script.*</script)>#iU', ' ', $mod_text);
+	$mod_text = preg_replace('#<(br( /)?|dt|/dd|/?(h[1-6]|tr|table|p|li|ul|pre|code|div|hr))[^>]*>#i', '.', $mod_text);
+	// $mod_text = preg_replace('/(\v\s?|\s\s)+/', ' ', $mod_text);
+	$mod_text = preg_replace('/\s\./', '.', $mod_text);
+	if($mod_ext_charset!='') { // data from external database may have a different charset
+		require_once(WB_PATH.'/framework/functions-utf8.php');
+		switch($mod_ext_charset) {
+		case 'latin1':
+		case 'cp1252':
+			$mod_text = charset_to_utf8($mod_text, 'CP1252');
+			break;
+		case 'cp1251':
+			$mod_text = charset_to_utf8($mod_text, 'CP1251');
+			break;
+		case 'latin2':
+			$mod_text = charset_to_utf8($mod_text, 'ISO-8859-2');
+			break;
+		case 'hebrew':
+			$mod_text = charset_to_utf8($mod_text, 'ISO-8859-8');
+			break;
+		case 'greek':
+			$mod_text = charset_to_utf8($mod_text, 'ISO-8859-7');
+			break;
+		case 'latin5':
+			$mod_text = charset_to_utf8($mod_text, 'ISO-8859-9');
+			break;
+		case 'latin7':
+			$mod_text = charset_to_utf8($mod_text, 'ISO-8859-13');
+			break;
+		case 'utf8':
+		default:
+			$mod_text = charset_to_utf8($mod_text, 'UTF-8');
+		}
+	} else {
+	$mod_text = entities_to_umlauts($mod_text, 'UTF-8');
+	}
+	$anchor_text = $mod_text; // make an copy containing html-tags
+	$mod_text = strip_tags($mod_text);
+	$mod_text = str_replace(array('&gt;','&lt;','&amp;','&quot;','&#039;','&apos;','&nbsp;'), array('>','<','&','"','\'','\'',"\xC2\xA0"), $mod_text);
+	$mod_text = '.'.trim($mod_text).'.';
+	// Do a fast scan over $mod_text first. This will speedup things a lot.
+	if($func_search_match == 'all') {
+		if(!is_all_matched($mod_text, $func_search_words))
+			return false;
+	}
+	elseif(!is_any_matched($mod_text, $func_search_words)) {
+		return false;
+	}
+	// search for an better anchor - this have to be done before strip_tags() (may fail if search-string contains <, &, amp, gt, lt, ...)
+	$anchor =  make_url_target($mod_page_link_target, $anchor_text, $func_search_words);
+
+	// make the link from $mod_page_link, add anchor
+	$link = "";
+	$link = page_link($mod_page_link);
+	if(strpos($mod_page_link, 'http:')===FALSE)
+		$link .= make_url_searchstring($func_search_match, $func_search_url_array);
+	$link .= $anchor;
+
+	// now get the excerpt
+	$excerpt = "";
+	$excerpt_array = array();
+	if($mod_max_excerpt_num > 0) {
+		if(!$excerpt_array = get_excerpts($mod_text, $func_search_words, $mod_max_excerpt_num)) {
+			return false;
+		}
+		$excerpt = prepare_excerpts($excerpt_array, $func_search_words, $mod_max_excerpt_num);
+	}
+
+	// handle thumbs - to deactivate this look in the module's search.php: $show_thumb (or maybe in the module's settings-page)
+	if($mod_pic_link != "") {
+		$excerpt = '<table class="excerpt_thumb" width="100%" cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="110" valign="top"><a href="'.$link.'"><img src="'.WB_URL.'/'.MEDIA_DIRECTORY.$mod_pic_link.'" alt="" /></a></td><td>'.$excerpt.'</td></tr></tbody></table>';
+	}
+
+	// print-out the excerpt
+	$vars = array();
+	$values = array();
+	list($date, $time) = get_page_modified($mod_page_modified_when);
+	list($username, $displayname) = get_page_modified_by($mod_page_modified_by, $func_users);
+	$vars = array('[LINK]', '[TITLE]', '[DESCRIPTION]', '[USERNAME]','[DISPLAY_NAME]','[DATE]','[TIME]','[TEXT_LAST_UPDATED_BY]','[TEXT_ON]','[EXCERPT]');
+	$values = array(
+		$link,
+		$mod_page_title,
+		$mod_page_description,
+		$username,
+		$displayname,
+		$date,
+		$time,
+		$TEXT['LAST_UPDATED_BY'],
+		$TEXT['ON'],
+		$excerpt
+	);
+	echo str_replace($vars, $values, $func_results_loop_string);
+	if($func_enable_flush) { // ATTN: this will bypass output-filters and may break template-layout or -filters
+		ob_flush();flush();
+	}
+	return true;
+}
+
+// list all files and dirs in $dir (recursive), omits '.', '..', and hidden files/dirs
+// returns an array of two arrays ($files[] and $dirs[]).
+// usage: list($files,$dirs) = list_files_dirs($directory);
+//        $depth: get subdirs (true/false)
+function list_files_dirs($dir, $depth=true, $files=array(), $dirs=array()) {
+	$dh=opendir($dir);
+	while(($file = readdir($dh)) !== false) {
+		if($file{0} == '.' || $file == '..') {
+			continue;
+		}
+		if(is_dir($dir.'/'.$file)) {
+			if($depth) {
+				$dirs[] = $dir.'/'.$file;
+				list($files, $dirs) = list_files_dirs($dir.'/'.$file, $depth, $files, $dirs);
+			}
+		} else {
+			$files[] = $dir.'/'.$file;
+		}
+	}
+	closedir($dh);
+	natcasesort($files);
+	natcasesort($dirs);
+	return(array($files, $dirs));
+}
+
+// keeps only wanted entries in array $files. $str have to be an eregi()-compatible regex
+/*
+function clear_filelist($files, $str, $keep=true)
+{
+	// options: $keep = true  : remove all non-matching entries
+	//          $keep = false : remove all matching entries
+	$c_filelist = array();
+	if($str == '')
+		return $files;
+	foreach($files as $file)
+    {
+		if($keep)
+        {
+			if(eregi($str, $file))
+            {
+				$c_filelist[] = $file;
+			}
+		} else {
+			if(!eregi($str, $file))
+            {
+				$c_filelist[] = $file;
+			}
+		}
+	}
+	return($c_filelist);
+}
+*/
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/wrapper/view.php
===================================================================
--- branches/2.8.x/wb/modules/wrapper/view.php	(revision 1419)
+++ branches/2.8.x/wb/modules/wrapper/view.php	(revision 1420)
@@ -16,6 +16,9 @@
  *
  */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
 // check if module language file exists for the language set by the user (e.g. DE, EN)
 if(!file_exists(WB_PATH .'/modules/wrapper/languages/'.LANGUAGE .'.php')) {
 	// no module language file exists for the language set by the user, include default module language file EN.php
Index: branches/2.8.x/wb/modules/wrapper/delete.php
===================================================================
--- branches/2.8.x/wb/modules/wrapper/delete.php	(revision 1419)
+++ branches/2.8.x/wb/modules/wrapper/delete.php	(revision 1420)
@@ -16,6 +16,9 @@
  *
  */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
 // Delete page from mod_wrapper
 $database->query("DELETE FROM ".TABLE_PREFIX."mod_wrapper WHERE section_id = '$section_id'");
 
Index: branches/2.8.x/wb/modules/wrapper/modify.php
===================================================================
--- branches/2.8.x/wb/modules/wrapper/modify.php	(revision 1419)
+++ branches/2.8.x/wb/modules/wrapper/modify.php	(revision 1420)
@@ -16,6 +16,9 @@
  *
  */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
 // Setup template object
 $template = new Template(WB_PATH.'/modules/wrapper');
 $template->set_file('page', 'modify.htt');
Index: branches/2.8.x/wb/modules/wrapper/add.php
===================================================================
--- branches/2.8.x/wb/modules/wrapper/add.php	(revision 1419)
+++ branches/2.8.x/wb/modules/wrapper/add.php	(revision 1420)
@@ -16,6 +16,9 @@
  *
  */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
 // Insert an extra row into the database
 $database->query("INSERT INTO ".TABLE_PREFIX."mod_wrapper (page_id,section_id,height) VALUES ('$page_id','$section_id','400')");
 
Index: branches/2.8.x/wb/modules/menu_link/view.php
===================================================================
--- branches/2.8.x/wb/modules/menu_link/view.php	(revision 1419)
+++ branches/2.8.x/wb/modules/menu_link/view.php	(revision 1420)
@@ -16,6 +16,9 @@
  *
  */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
 // check if module language file exists for the language set by the user (e.g. DE, EN)
 if(!file_exists(WB_PATH .'/modules/menu_link/languages/'.LANGUAGE .'.php')) {
 	// no module language file exists for the language set by the user, include default module language file EN.php
Index: branches/2.8.x/wb/modules/wysiwyg/view.php
===================================================================
--- branches/2.8.x/wb/modules/wysiwyg/view.php	(revision 1419)
+++ branches/2.8.x/wb/modules/wysiwyg/view.php	(revision 1420)
@@ -1,26 +1,27 @@
-<?php
-/**
- *
- * @category        modules
- * @package         wysiwyg
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// Get content
-$get_content = $database->query("SELECT content FROM ".TABLE_PREFIX."mod_wysiwyg WHERE section_id = '$section_id'");
-$fetch_content = $get_content->fetchRow();
-$content = ($fetch_content['content']);
-
-echo $content;
-
+<?php
+/**
+ *
+ * @category        modules
+ * @package         wysiwyg
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+// Get content
+$get_content = $database->query("SELECT content FROM ".TABLE_PREFIX."mod_wysiwyg WHERE section_id = '$section_id'");
+$fetch_content = $get_content->fetchRow();
+$content = ($fetch_content['content']);
+
+echo $content;
+
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/wysiwyg/delete.php
===================================================================
--- branches/2.8.x/wb/modules/wysiwyg/delete.php	(revision 1419)
+++ branches/2.8.x/wb/modules/wysiwyg/delete.php	(revision 1420)
@@ -15,7 +15,8 @@
  * @lastmodified    $Date: 2011-01-10 13:21:47 +0100 (Mo, 10 Jan 2011) $
  *
  */
-
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 // Delete record from the database
 $database->query("DELETE FROM ".TABLE_PREFIX."mod_wysiwyg WHERE section_id = '$section_id'");
 
Index: branches/2.8.x/wb/modules/wysiwyg/search.php
===================================================================
--- branches/2.8.x/wb/modules/wysiwyg/search.php	(revision 1419)
+++ branches/2.8.x/wb/modules/wysiwyg/search.php	(revision 1420)
@@ -15,6 +15,8 @@
  * @lastmodified    $Date: 2011-01-10 13:21:47 +0100 (Mo, 10. Jan 2011) $
  *
  */
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 function wysiwyg_search($func_vars) {
 	extract($func_vars, EXTR_PREFIX_ALL, 'func');
Index: branches/2.8.x/wb/modules/wysiwyg/add.php
===================================================================
--- branches/2.8.x/wb/modules/wysiwyg/add.php	(revision 1419)
+++ branches/2.8.x/wb/modules/wysiwyg/add.php	(revision 1420)
@@ -15,7 +15,8 @@
  * @lastmodified    $Date: 2011-01-10 13:21:47 +0100 (Mo, 10 Jan 2011) $
  *
  */
-
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 // Insert an extra row into the database
 $database->query("INSERT INTO ".TABLE_PREFIX."mod_wysiwyg (page_id,section_id) VALUES ('$page_id','$section_id')");
 
Index: branches/2.8.x/wb/modules/captcha_control/tool.php
===================================================================
--- branches/2.8.x/wb/modules/captcha_control/tool.php	(revision 1419)
+++ branches/2.8.x/wb/modules/captcha_control/tool.php	(revision 1420)
@@ -1,204 +1,204 @@
-<?php
-
-// $Id$
-
-/*
-
- Website Baker Project <http://www.websitebaker.org/>
- Copyright (C) 2004-2009, Ryan Djurovich
-
- Website Baker is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- Website Baker is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Website Baker; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-// direct access prevention
-defined('WB_PATH') OR die(header('Location: ../index.php'));
-
-// check if module language file exists for the language set by the user (e.g. DE, EN)
-if(!file_exists(WB_PATH .'/modules/captcha_control/languages/'.LANGUAGE .'.php')) {
-	// no module language file exists for the language set by the user, include default module language file EN.php
-	require_once(WB_PATH .'/modules/captcha_control/languages/EN.php');
-} else {
-	// a module language file exists for the language defined by the user, load it
-	require_once(WB_PATH .'/modules/captcha_control/languages/'.LANGUAGE .'.php');
-}
-
-$table = TABLE_PREFIX.'mod_captcha_control';
-$js_back = "javascript: history.go(-1);";
-
-// check if data was submitted
-if(isset($_POST['save_settings'])) {
-	if (!$admin->checkFTAN())
-	{
-		$admin->print_error($MESSAGE['GENERIC_SECURITY_ACCESS'], ADMIN_URL);
-		exit();
-	}
-	
-	// get configuration settings
-	$enabled_captcha = ($_POST['enabled_captcha'] == '1') ? '1' : '0';
-	$enabled_asp = ($_POST['enabled_asp'] == '1') ? '1' : '0';
-	$captcha_type = $admin->add_slashes($_POST['captcha_type']);
-	
-	// update database settings
-	$database->query("UPDATE $table SET
-		enabled_captcha = '$enabled_captcha',
-		enabled_asp = '$enabled_asp',
-		captcha_type = '$captcha_type'
-	");
-
-	// save text-captchas
-	if($captcha_type == 'text') { // ct_text
-		$text_qa=$admin->add_slashes($_POST['text_qa']);
-		if(!preg_match('/### .*? ###/', $text_qa)) {
-			$database->query("UPDATE $table SET ct_text = '$text_qa'");
-		}
-	}
-	
-	// check if there is a database error, otherwise say successful
-	if($database->is_error()) {
-		$admin->print_error($database->get_error(), $js_back);
-	} else {
-		$admin->print_success($MESSAGE['PAGES']['SAVED'], ADMIN_URL.'/admintools/tool.php?tool=captcha_control');
-	}
-
-} else {
-	
-	// include captcha-file
-	require_once(WB_PATH .'/include/captcha/captcha.php');
-
-	// load text-captchas
-	$text_qa='';
-	if($query = $database->query("SELECT ct_text FROM $table")) {
-		$data = $query->fetchRow();
-		$text_qa = $data['ct_text'];
-	}
-	if($text_qa == '')
-		$text_qa = $MOD_CAPTCHA_CONTROL['CAPTCHA_TEXT_DESC'];
-
-// script to load image
-?>
-<script type="text/javascript">
-	var pics = new Array();
-
-	pics["ttf_image"] = new Image();
-	pics["ttf_image"].src = "<?php echo WB_URL.'/include/captcha/captchas/ttf_image.png'?>";
-
-	pics["calc_image"] = new Image();
-	pics["calc_image"].src = "<?php echo WB_URL.'/include/captcha/captchas/calc_image.png'?>";
-
-	pics["calc_ttf_image"] = new Image();
-	pics["calc_ttf_image"].src = "<?php echo WB_URL.'/include/captcha/captchas/calc_ttf_image.png'?>";
-
-	pics["old_image"] = new Image();
-	pics["old_image"].src = "<?php echo WB_URL.'/include/captcha/captchas/old_image.png'?>";
-	
-	pics["calc_text"] = new Image();
-	pics["calc_text"].src = "<?php echo WB_URL.'/include/captcha/captchas/calc_text.png'?>";
-	
-	pics["text"] = new Image();
-	pics["text"].src = "<?php echo WB_URL.'/include/captcha/captchas/text.png'?>";
-
-	function load_captcha_image() {
-		document.captcha_example.src = pics[document.store_settings.captcha_type.value].src;
-		toggle_text_qa();
-	}
-	
-	function toggle_text_qa() {
-		if(document.store_settings.captcha_type.value == 'text' ) {
-			document.getElementById('text_qa').style.display = '';
-		} else {
-			document.getElementById('text_qa').style.display = 'none';
-		}
-	}
-
-</script>
-<?php
-
-	// connect to database and read out captcha settings
-	if($query = $database->query("SELECT * FROM $table")) {
-		$data = $query->fetchRow();
-		$enabled_captcha = $data['enabled_captcha'];
-		$enabled_asp = $data['enabled_asp'];
-		$captcha_type = $data['captcha_type'];
-	} else {
-		// something went wrong, use dummy value
-		$enabled_captcha = '1';
-		$enabled_asp = '1';
-		$captcha_type = 'calc_text';
-	}
-		
-	// write out heading
-	echo '<h2>' .$MOD_CAPTCHA_CONTROL['HEADING'] .'</h2>';
-
-	// output the form with values from the database
-	echo '<p>' .$MOD_CAPTCHA_CONTROL['HOWTO'] .'</p>';
-?>
-<form name="store_settings" action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post">
-	<?php echo $admin->getFTAN(); ?>
-	<table width="98%" cellspacing="0" border="0" cellpadding="5px" class="row_a">
-	<tr><td colspan="2"><strong><?php echo $MOD_CAPTCHA_CONTROL['CAPTCHA_CONF'];?>:</strong></td></tr>
-	<tr>
-		<td width="30%"><?php echo $MOD_CAPTCHA_CONTROL['CAPTCHA_TYPE'];?>:</td>
-		<td>
-		<select name="captcha_type" id="captcha_type" onchange="load_captcha_image()" style="width: 98%;">
-			<?php foreach($useable_captchas AS $key=>$text) {
-			echo "<option value=\"$key\" ".($captcha_type==$key ? ' selected="selected"' : '').">$text</option>";
-			} ?>
-		</select>
-		</td>
-	</tr>
-	<tr>
-		<td>&nbsp;</td>
-		<td align="left" width="150px">
-            <img alt="captcha_example" id="captcha_example" src="<?php echo WB_URL.'/include/captcha/captchas/'.$captcha_type.'.png'?>" />
-        </td>
-	</tr>
-	<tr id="text_qa" style="display:<?php if($captcha_type=='text') echo ''; else echo 'none'; ;?>;">
-		<td valign="top" class="setting_name"><?php echo $MOD_CAPTCHA_CONTROL['CAPTCHA_ENTER_TEXT'];?>:</td>
-		<td class="setting_value" colspan="2">
-			<textarea name="text_qa" cols="60" rows="10"><?php echo $text_qa; ?></textarea>
-		</td>
-	</tr>
-	<tr>
-		<td><?php echo $MOD_CAPTCHA_CONTROL['USE_SIGNUP_CAPTCHA'];?>:</td>
-		<td>
-			<input type="radio" <?php echo ($enabled_captcha=='1') ?'checked="checked"' :'';?>
-				name="enabled_captcha" value="1" /><?php echo $MOD_CAPTCHA_CONTROL['ENABLED'];?>
-			<input type="radio" <?php echo ($enabled_captcha=='0') ?'checked="checked"' :'';?>
-				name="enabled_captcha" value="0" /><?php echo $MOD_CAPTCHA_CONTROL['DISABLED'];?>
-		</td>
-	</tr>
-	<tr><td>&nbsp;</td><td style="font-size:smaller;"><?php echo $MOD_CAPTCHA_CONTROL['CAPTCHA_EXP'];?></td></tr>
-	<tr><td colspan="2"><br /><strong><?php echo $MOD_CAPTCHA_CONTROL['ASP_CONF'];?>:</strong></td></tr>
-	<tr>
-		<td><?php echo $MOD_CAPTCHA_CONTROL['ASP_TEXT'];?>:</td>
-		<td>
-			<input type="radio" <?php echo ($enabled_asp=='1') ?'checked="checked"' :'';?>
-				name="enabled_asp" value="1" /><?php echo $MOD_CAPTCHA_CONTROL['ENABLED'];?>
-			<input type="radio" <?php echo ($enabled_asp=='0') ?'checked="checked"' :'';?>
-				name="enabled_asp" value="0" /><?php echo $MOD_CAPTCHA_CONTROL['DISABLED'];?>
-		</td>
-	</tr>
-	<tr>
-        <td>&nbsp;</td>
-        <td style="font-size:smaller;"><?php echo $MOD_CAPTCHA_CONTROL['ASP_EXP'];?></td>
-    </tr>
-	</table>
-	<input type="submit" name="save_settings" style="margin-top:10px; width:140px;" value="<?php echo $TEXT['SAVE']; ?>" />
-</form>
-<?php
-}
-
+<?php
+
+// $Id$
+
+/*
+
+ Website Baker Project <http://www.websitebaker.org/>
+ Copyright (C) 2004-2009, Ryan Djurovich
+
+ Website Baker is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Website Baker is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Website Baker; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+
+// check if module language file exists for the language set by the user (e.g. DE, EN)
+if(!file_exists(WB_PATH .'/modules/captcha_control/languages/'.LANGUAGE .'.php')) {
+	// no module language file exists for the language set by the user, include default module language file EN.php
+	require_once(WB_PATH .'/modules/captcha_control/languages/EN.php');
+} else {
+	// a module language file exists for the language defined by the user, load it
+	require_once(WB_PATH .'/modules/captcha_control/languages/'.LANGUAGE .'.php');
+}
+
+$table = TABLE_PREFIX.'mod_captcha_control';
+$js_back = "javascript: history.go(-1);";
+
+// check if data was submitted
+if(isset($_POST['save_settings'])) {
+	if (!$admin->checkFTAN())
+	{
+		$admin->print_error($MESSAGE['GENERIC_SECURITY_ACCESS'], ADMIN_URL);
+		exit();
+	}
+	
+	// get configuration settings
+	$enabled_captcha = ($_POST['enabled_captcha'] == '1') ? '1' : '0';
+	$enabled_asp = ($_POST['enabled_asp'] == '1') ? '1' : '0';
+	$captcha_type = $admin->add_slashes($_POST['captcha_type']);
+	
+	// update database settings
+	$database->query("UPDATE $table SET
+		enabled_captcha = '$enabled_captcha',
+		enabled_asp = '$enabled_asp',
+		captcha_type = '$captcha_type'
+	");
+
+	// save text-captchas
+	if($captcha_type == 'text') { // ct_text
+		$text_qa=$admin->add_slashes($_POST['text_qa']);
+		if(!preg_match('/### .*? ###/', $text_qa)) {
+			$database->query("UPDATE $table SET ct_text = '$text_qa'");
+		}
+	}
+	
+	// check if there is a database error, otherwise say successful
+	if($database->is_error()) {
+		$admin->print_error($database->get_error(), $js_back);
+	} else {
+		$admin->print_success($MESSAGE['PAGES']['SAVED'], ADMIN_URL.'/admintools/tool.php?tool=captcha_control');
+	}
+
+} else {
+	
+	// include captcha-file
+	require_once(WB_PATH .'/include/captcha/captcha.php');
+
+	// load text-captchas
+	$text_qa='';
+	if($query = $database->query("SELECT ct_text FROM $table")) {
+		$data = $query->fetchRow();
+		$text_qa = $data['ct_text'];
+	}
+	if($text_qa == '')
+		$text_qa = $MOD_CAPTCHA_CONTROL['CAPTCHA_TEXT_DESC'];
+
+// script to load image
+?>
+<script type="text/javascript">
+	var pics = new Array();
+
+	pics["ttf_image"] = new Image();
+	pics["ttf_image"].src = "<?php echo WB_URL.'/include/captcha/captchas/ttf_image.png'?>";
+
+	pics["calc_image"] = new Image();
+	pics["calc_image"].src = "<?php echo WB_URL.'/include/captcha/captchas/calc_image.png'?>";
+
+	pics["calc_ttf_image"] = new Image();
+	pics["calc_ttf_image"].src = "<?php echo WB_URL.'/include/captcha/captchas/calc_ttf_image.png'?>";
+
+	pics["old_image"] = new Image();
+	pics["old_image"].src = "<?php echo WB_URL.'/include/captcha/captchas/old_image.png'?>";
+	
+	pics["calc_text"] = new Image();
+	pics["calc_text"].src = "<?php echo WB_URL.'/include/captcha/captchas/calc_text.png'?>";
+	
+	pics["text"] = new Image();
+	pics["text"].src = "<?php echo WB_URL.'/include/captcha/captchas/text.png'?>";
+
+	function load_captcha_image() {
+		document.captcha_example.src = pics[document.store_settings.captcha_type.value].src;
+		toggle_text_qa();
+	}
+	
+	function toggle_text_qa() {
+		if(document.store_settings.captcha_type.value == 'text' ) {
+			document.getElementById('text_qa').style.display = '';
+		} else {
+			document.getElementById('text_qa').style.display = 'none';
+		}
+	}
+
+</script>
+<?php
+
+	// connect to database and read out captcha settings
+	if($query = $database->query("SELECT * FROM $table")) {
+		$data = $query->fetchRow();
+		$enabled_captcha = $data['enabled_captcha'];
+		$enabled_asp = $data['enabled_asp'];
+		$captcha_type = $data['captcha_type'];
+	} else {
+		// something went wrong, use dummy value
+		$enabled_captcha = '1';
+		$enabled_asp = '1';
+		$captcha_type = 'calc_text';
+	}
+		
+	// write out heading
+	echo '<h2>' .$MOD_CAPTCHA_CONTROL['HEADING'] .'</h2>';
+
+	// output the form with values from the database
+	echo '<p>' .$MOD_CAPTCHA_CONTROL['HOWTO'] .'</p>';
+?>
+<form name="store_settings" action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post">
+	<?php echo $admin->getFTAN(); ?>
+	<table width="98%" cellspacing="0" border="0" cellpadding="5px" class="row_a">
+	<tr><td colspan="2"><strong><?php echo $MOD_CAPTCHA_CONTROL['CAPTCHA_CONF'];?>:</strong></td></tr>
+	<tr>
+		<td width="30%"><?php echo $MOD_CAPTCHA_CONTROL['CAPTCHA_TYPE'];?>:</td>
+		<td>
+		<select name="captcha_type" id="captcha_type" onchange="load_captcha_image()" style="width: 98%;">
+			<?php foreach($useable_captchas AS $key=>$text) {
+			echo "<option value=\"$key\" ".($captcha_type==$key ? ' selected="selected"' : '').">$text</option>";
+			} ?>
+		</select>
+		</td>
+	</tr>
+	<tr>
+		<td>&nbsp;</td>
+		<td align="left" width="150px">
+            <img alt="captcha_example" id="captcha_example" src="<?php echo WB_URL.'/include/captcha/captchas/'.$captcha_type.'.png'?>" />
+        </td>
+	</tr>
+	<tr id="text_qa" style="display:<?php if($captcha_type=='text') echo ''; else echo 'none'; ;?>;">
+		<td valign="top" class="setting_name"><?php echo $MOD_CAPTCHA_CONTROL['CAPTCHA_ENTER_TEXT'];?>:</td>
+		<td class="setting_value" colspan="2">
+			<textarea name="text_qa" cols="60" rows="10"><?php echo $text_qa; ?></textarea>
+		</td>
+	</tr>
+	<tr>
+		<td><?php echo $MOD_CAPTCHA_CONTROL['USE_SIGNUP_CAPTCHA'];?>:</td>
+		<td>
+			<input type="radio" <?php echo ($enabled_captcha=='1') ?'checked="checked"' :'';?>
+				name="enabled_captcha" value="1" /><?php echo $MOD_CAPTCHA_CONTROL['ENABLED'];?>
+			<input type="radio" <?php echo ($enabled_captcha=='0') ?'checked="checked"' :'';?>
+				name="enabled_captcha" value="0" /><?php echo $MOD_CAPTCHA_CONTROL['DISABLED'];?>
+		</td>
+	</tr>
+	<tr><td>&nbsp;</td><td style="font-size:smaller;"><?php echo $MOD_CAPTCHA_CONTROL['CAPTCHA_EXP'];?></td></tr>
+	<tr><td colspan="2"><br /><strong><?php echo $MOD_CAPTCHA_CONTROL['ASP_CONF'];?>:</strong></td></tr>
+	<tr>
+		<td><?php echo $MOD_CAPTCHA_CONTROL['ASP_TEXT'];?>:</td>
+		<td>
+			<input type="radio" <?php echo ($enabled_asp=='1') ?'checked="checked"' :'';?>
+				name="enabled_asp" value="1" /><?php echo $MOD_CAPTCHA_CONTROL['ENABLED'];?>
+			<input type="radio" <?php echo ($enabled_asp=='0') ?'checked="checked"' :'';?>
+				name="enabled_asp" value="0" /><?php echo $MOD_CAPTCHA_CONTROL['DISABLED'];?>
+		</td>
+	</tr>
+	<tr>
+        <td>&nbsp;</td>
+        <td style="font-size:smaller;"><?php echo $MOD_CAPTCHA_CONTROL['ASP_EXP'];?></td>
+    </tr>
+	</table>
+	<input type="submit" name="save_settings" style="margin-top:10px; width:140px;" value="<?php echo $TEXT['SAVE']; ?>" />
+</form>
+<?php
+}
+
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/form/search.php
===================================================================
--- branches/2.8.x/wb/modules/form/search.php	(revision 1419)
+++ branches/2.8.x/wb/modules/form/search.php	(revision 1420)
@@ -15,6 +15,8 @@
  * @lastmodified    $Date:  $
  * @description     
  */
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 function form_search($func_vars) {
 	extract($func_vars, EXTR_PREFIX_ALL, 'func');
Index: branches/2.8.x/wb/modules/form/add.php
===================================================================
--- branches/2.8.x/wb/modules/form/add.php	(revision 1419)
+++ branches/2.8.x/wb/modules/form/add.php	(revision 1420)
@@ -15,6 +15,8 @@
  * @lastmodified    $Date:  $
  * @description     
  */
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 // Insert an extra rows into the database
 $header = '<table cellpadding=\"2\" cellspacing=\"0\" border=\"0\" width=\"98%\">';
Index: branches/2.8.x/wb/modules/jsadmin/tool.php
===================================================================
--- branches/2.8.x/wb/modules/jsadmin/tool.php	(revision 1419)
+++ branches/2.8.x/wb/modules/jsadmin/tool.php	(revision 1420)
@@ -16,8 +16,8 @@
  *
 */
 
-// direct access prevention
-defined('WB_PATH') OR die(header('Location: ../index.php'));
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 // check if module language file exists for the language set by the user (e.g. DE, EN)
 if(!file_exists(WB_PATH .'/modules/jsadmin/languages/'.LANGUAGE .'.php')) {
Index: branches/2.8.x/wb/modules/jsadmin/jsadmin_backend_include.php
===================================================================
--- branches/2.8.x/wb/modules/jsadmin/jsadmin_backend_include.php	(revision 1419)
+++ branches/2.8.x/wb/modules/jsadmin/jsadmin_backend_include.php	(revision 1420)
@@ -1,101 +1,102 @@
-<?php
-/**
- *
- * @category        modules
- * @package         JsAdmin
- * @author          WebsiteBaker Project, modified by Swen Uth for Website Baker 2.7
- * @copyright       (C) 2006, Stepan Riha
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL: http://svn.websitebaker2.org/branches/2.8.x/wb/modules/menu_link/save.php $
- * @lastmodified    $Date: 2011-01-10 13:21:47 +0100 (Mo, 10 Jan 2011) $
- *
-*/
-
-// Direct access prevention
-defined('WB_PATH') OR die(header('Location: ../index.php'));
-
-// obtain the admin folder (e.g. /admin)
-$admin_folder = str_replace(WB_PATH, '', ADMIN_PATH);
-
-$JSADMIN_PATH = WB_URL.'/modules/jsadmin';
-$YUI_PATH = WB_URL.'/include/yui';
-$script = $_SERVER['SCRIPT_NAME'];
-
-if(strstr($script, $admin_folder."/pages/index.php"))
-	$page_type = 'pages';
-elseif(strstr($script, $admin_folder."/pages/sections.php"))
-	$page_type = 'sections';
-elseif(strstr($script, $admin_folder."/settings/tool.php")
-	&& isset($_REQUEST["tool"]) && $_REQUEST["tool"] == 'jsadmin')
-	$page_type = 'config';
-else
-	$page_type = '';
-if($page_type) {
-	require_once(WB_PATH.'/modules/jsadmin/jsadmin.php');
-
-	// Default scripts
-	$js_buttonCell = 3;
-	$js_scripts = Array();
-	$js_scripts[] = 'jsadmin.js';
-
-	if($page_type == 'pages') {
-		if(!get_setting('mod_jsadmin_persist_order', '1')) {   //Maybe Bug settings to negativ for persist , by Swen Uth
-			$js_scripts[] = 'restore_pages.js';
-  		}
-		if(get_setting('mod_jsadmin_ajax_order_pages', '1')) {
-			$js_scripts[] = 'dragdrop.js';
-			$js_buttonCell= 7; // This ist the Cell where the Button "Up" is , by Swen Uth
-		}
-	} elseif($page_type == 'sections') {
-		if(get_setting('mod_jsadmin_ajax_order_sections', '1')) {
-			$js_scripts[] = 'dragdrop.js';
-			if(SECTION_BLOCKS) {
-			$js_buttonCell= 5;}
-      else{ $js_buttonCell= 5;} // This ist the Cell where the Button "Up" is , by Swen Uth
-		}
-	} elseif($page_type == 'config') {
-		$js_scripts[] = 'tool.js';
-	}
-?>
-
-<script  type="text/javascript" language="JavaScript">
-<!--
-var JsAdmin = { WB_URL : '<?php echo WB_URL ?>', ADMIN_URL : '<?php echo ADMIN_URL ?>' };
-var JsAdminTheme = { THEME_URL : '<?php echo THEME_URL ?>' };
-//-->
-</script>
-<?php
- // For variable cell structure in the tables of admin content
-  echo "<script type='text/javascript'>buttonCell=".$js_buttonCell.";</script>\n";   // , by Swen  Uth
-
- // Check and Load the needed YUI functions  //, all by Swen Uth
-  $YUI_ERROR=false; // ist there an Error
-  $YUI_PUT ='';   // String with javascipt includes
-  $YUI_PUT_MISSING_Files=''; // Strin with missing files
-  reset($js_yui_scripts);
-  foreach($js_yui_scripts as $script) {
-    if(file_exists($WB_MAIN_RELATIVE_PATH.$script)){
-        $YUI_PUT=$YUI_PUT."<script type='text/javascript' src='".$WB_MAIN_RELATIVE_PATH.$script."'></script>\n"; // go and include
-    } else {
-        $YUI_ERROR=true;
-        $YUI_PUT_MISSING_Files=$YUI_PUT_MISSING_Files."- ".WB_URL.$script."\\n";   // catch all missing files
-    }
-	}
-	if(!$YUI_ERROR)
-	{
-    echo $YUI_PUT;  // no Error so go and include
-    // Load the needed functions
-	  foreach($js_scripts as $script) {
-		  echo "<script type='text/javascript' src='".$JSADMIN_PATH."/js/".$script."'></script>\n";
-	  }
-  } else  {
-      echo "<script type='text/javascript'>alert('YUI ERROR!! File not Found!! > \\n".$YUI_PUT_MISSING_Files." so look in the include folder or switch Javascript Admin off!');</script>\n"; //, by Swen Uth
-  }
-
- }
+<?php
+/**
+ *
+ * @category        modules
+ * @package         JsAdmin
+ * @author          WebsiteBaker Project, modified by Swen Uth for Website Baker 2.7
+ * @copyright       (C) 2006, Stepan Riha
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL: http://svn.websitebaker2.org/branches/2.8.x/wb/modules/menu_link/save.php $
+ * @lastmodified    $Date: 2011-01-10 13:21:47 +0100 (Mo, 10 Jan 2011) $
+ *
+*/
+
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+// obtain the admin folder (e.g. /admin)
+$admin_folder = str_replace(WB_PATH, '', ADMIN_PATH);
+
+$JSADMIN_PATH = WB_URL.'/modules/jsadmin';
+$YUI_PATH = WB_URL.'/include/yui';
+$script = $_SERVER['SCRIPT_NAME'];
+
+if(strstr($script, $admin_folder."/pages/index.php"))
+	$page_type = 'pages';
+elseif(strstr($script, $admin_folder."/pages/sections.php"))
+	$page_type = 'sections';
+elseif(strstr($script, $admin_folder."/settings/tool.php")
+	&& isset($_REQUEST["tool"]) && $_REQUEST["tool"] == 'jsadmin')
+	$page_type = 'config';
+else
+	$page_type = '';
+if($page_type) {
+	require_once(WB_PATH.'/modules/jsadmin/jsadmin.php');
+
+	// Default scripts
+	$js_buttonCell = 3;
+	$js_scripts = Array();
+	$js_scripts[] = 'jsadmin.js';
+
+	if($page_type == 'pages') {
+		if(!get_setting('mod_jsadmin_persist_order', '1')) {   //Maybe Bug settings to negativ for persist , by Swen Uth
+			$js_scripts[] = 'restore_pages.js';
+  		}
+		if(get_setting('mod_jsadmin_ajax_order_pages', '1')) {
+			$js_scripts[] = 'dragdrop.js';
+			$js_buttonCell= 7; // This ist the Cell where the Button "Up" is , by Swen Uth
+		}
+	} elseif($page_type == 'sections') {
+		if(get_setting('mod_jsadmin_ajax_order_sections', '1')) {
+			$js_scripts[] = 'dragdrop.js';
+			if(SECTION_BLOCKS) {
+			$js_buttonCell= 5;}
+      else{ $js_buttonCell= 5;} // This ist the Cell where the Button "Up" is , by Swen Uth
+		}
+	} elseif($page_type == 'config') {
+		$js_scripts[] = 'tool.js';
+	}
+?>
+
+<script  type="text/javascript" language="JavaScript">
+<!--
+var JsAdmin = { WB_URL : '<?php echo WB_URL ?>', ADMIN_URL : '<?php echo ADMIN_URL ?>' };
+var JsAdminTheme = { THEME_URL : '<?php echo THEME_URL ?>' };
+//-->
+</script>
+<?php
+ // For variable cell structure in the tables of admin content
+  echo "<script type='text/javascript'>buttonCell=".$js_buttonCell.";</script>\n";   // , by Swen  Uth
+
+ // Check and Load the needed YUI functions  //, all by Swen Uth
+  $YUI_ERROR=false; // ist there an Error
+  $YUI_PUT ='';   // String with javascipt includes
+  $YUI_PUT_MISSING_Files=''; // Strin with missing files
+  reset($js_yui_scripts);
+  foreach($js_yui_scripts as $script) {
+    if(file_exists($WB_MAIN_RELATIVE_PATH.$script)){
+        $YUI_PUT=$YUI_PUT."<script type='text/javascript' src='".$WB_MAIN_RELATIVE_PATH.$script."'></script>\n"; // go and include
+    } else {
+        $YUI_ERROR=true;
+        $YUI_PUT_MISSING_Files=$YUI_PUT_MISSING_Files."- ".WB_URL.$script."\\n";   // catch all missing files
+    }
+	}
+	if(!$YUI_ERROR)
+	{
+    echo $YUI_PUT;  // no Error so go and include
+    // Load the needed functions
+	  foreach($js_scripts as $script) {
+		  echo "<script type='text/javascript' src='".$JSADMIN_PATH."/js/".$script."'></script>\n";
+	  }
+  } else  {
+      echo "<script type='text/javascript'>alert('YUI ERROR!! File not Found!! > \\n".$YUI_PUT_MISSING_Files." so look in the include folder or switch Javascript Admin off!');</script>\n"; //, by Swen Uth
+  }
+
+ }
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/jsadmin/jsadmin.php
===================================================================
--- branches/2.8.x/wb/modules/jsadmin/jsadmin.php	(revision 1419)
+++ branches/2.8.x/wb/modules/jsadmin/jsadmin.php	(revision 1420)
@@ -16,6 +16,9 @@
  *
 */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
 function get_setting($name, $default = '') {
 	global $database;
 	$rs = $database->query("SELECT value FROM ".TABLE_PREFIX."mod_jsadmin WHERE name = '".$name."'");
Index: branches/2.8.x/wb/modules/output_filter/uninstall.php
===================================================================
--- branches/2.8.x/wb/modules/output_filter/uninstall.php	(revision 1419)
+++ branches/2.8.x/wb/modules/output_filter/uninstall.php	(revision 1420)
@@ -1,25 +1,25 @@
-<?php
-/**
- *
- * @category        modules
- * @package         output_filter
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// prevent this file from being accessed directly
-if(!defined('WB_PATH')) die(header('Location: ../index.php'));
-
-$table = TABLE_PREFIX .'mod_output_filter';
-$database->query("DROP TABLE IF EXISTS `$table`");
-
+<?php
+/**
+ *
+ * @category        modules
+ * @package         output_filter
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+$table = TABLE_PREFIX .'mod_output_filter';
+$database->query("DROP TABLE IF EXISTS `$table`");
+
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/output_filter/filter-routines.php
===================================================================
--- branches/2.8.x/wb/modules/output_filter/filter-routines.php	(revision 1419)
+++ branches/2.8.x/wb/modules/output_filter/filter-routines.php	(revision 1420)
@@ -1,212 +1,212 @@
-<?php
-/**
- *
- * @category        modules
- * @package         output_filter
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// prevent this file from being accessed directly
-if(!defined('WB_PATH')) die(header('Location: ../index.php'));
-
-// function to read the current filter settings
-if (!function_exists('get_output_filter_settings')) {
-	function get_output_filter_settings() {
-		global $database, $admin;
-		// connect to database and read out filter settings
-		$result = $database->query("SELECT * FROM " .TABLE_PREFIX ."mod_output_filter");
-		if($result && $result->numRows() > 0) {
-			// get all data
-			$data = $result->fetchRow();
-			$filter_settings['email_filter'] = $admin->strip_slashes($data['email_filter']);
-			$filter_settings['mailto_filter'] = $admin->strip_slashes($data['mailto_filter']);
-			$filter_settings['at_replacement'] = $admin->strip_slashes($data['at_replacement']);
-			$filter_settings['dot_replacement'] = $admin->strip_slashes($data['dot_replacement']);
-		} else {
-			// something went wrong, use default values
-			$filter_settings['email_filter'] = '0';
-			$filter_settings['mailto_filter'] = '0';
-			$filter_settings['at_replacement'] = '(at)';
-			$filter_settings['dot_replacement'] = '(dot)';
-		}
-		
-		// return array with filter settings
-		return $filter_settings;
-	}
-}
-
-// function to filter the output before displaying it on the frontend
-if (!function_exists('filter_frontend_output')) {
-	function filter_frontend_output($content) {
-		// get output filter settings from database
-		$filter_settings = get_output_filter_settings();
-		
-		// work out the defined output filter mode: possible output filter modes: [0], 1, 2, 3, 6, 7
-		// 2^0 * (0.. disable, 1.. enable) filtering of mail addresses in text
-		// 2^1 * (0.. disable, 1.. enable) filtering of mail addresses in mailto links
-		// 2^2 * (0.. disable, 1.. enable) Javascript mailto encryption (only if mailto filtering enabled)
-
-		// only filter output if we are supposed to
-		if($filter_settings['email_filter'] != '1' && $filter_settings['mailto_filter'] != '1'){
-			// nothing to do ...
-			return $content;
-		}
-
-		// check if non mailto mail addresses needs to be filtered
-		$output_filter_mode = ($filter_settings['email_filter'] == '1') ? 1 : 0;		// 0|1
-
-		// check if mailto mail addresses needs to be filtered
-		if($filter_settings['mailto_filter'] == '1') {
-			$output_filter_mode = $output_filter_mode + 2;								// 0|2
-
-			// check if Javascript mailto encryption is enabled (call register_frontend_functions in the template)
-           $search_pattern = '/<.*src=\".*\/mdcr.js.*>/iU';
-           if(preg_match($search_pattern, $content))
-           {
-            $output_filter_mode = $output_filter_mode + 4;       // 0|4
-           }
-/*
-			$search = '<script src="' .WB_URL .'/modules/output_filter/js/mdcr.js" type="text/javascript"></script>';
-			$search_droplet = '<script src="' .WB_URL .'/modules/droplets/js/mdcr.js" type="text/javascript"></script>';
-			if(strpos($content, $search) !== false || strpos($content, $search_droplet) !== false) {
-				$output_filter_mode = $output_filter_mode + 4;							// 0|4
-			}
-*/
-		}
-		
-		// define some constants so we do not call the database in the callback function again
-		define('OUTPUT_FILTER_MODE', (int) $output_filter_mode);
-		define('OUTPUT_FILTER_AT_REPLACEMENT', $filter_settings['at_replacement']);
-		define('OUTPUT_FILTER_DOT_REPLACEMENT', $filter_settings['dot_replacement']);
-		
-		// first search part to find all mailto email addresses
-		$pattern = '#(<a[^<]*href\s*?=\s*?"\s*?mailto\s*?:\s*?)([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})([^"]*?)"([^>]*>)(.*?)</a>';
-		// second part to find all non mailto email addresses
-		$pattern .= '|(value\s*=\s*"|\')??\b([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})\b#i';
-		/*
-		Sub 1:\b(<a.[^<]*href\s*?=\s*?"\s*?mailto\s*?:\s*?)			-->	"<a id="yyy" class="xxx" href = " mailto :" ignoring white spaces
-		Sub 2:([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})			-->	the email address in the mailto: part of the mail link
-		Sub 3:([^"]*?)"												--> possible ?Subject&cc... stuff attached to the mail address
-		Sub 4:([^>]*>)												--> all class or id statements after the mailto but before closing ..>
-		Sub 5:(.*?)</a>\b											--> the mailto text; all characters between >xxxxx</a>
-		Sub 6:|\b([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})\b		--> email addresses which may appear in the text (require word boundaries)
-		*/
-			
-		// find all email addresses embedded in the content and filter them using a callback function
-		$content = preg_replace_callback($pattern, 'filter_mail_addresses', $content);
-		return $content;
-	}
-}		
-
-
-// function to filter mail addresses embedded in text or mailto links before outputing them on the frontend
-if (!function_exists('filter_mail_addresses')) {
-	function filter_mail_addresses($match) { 
-		
-		// check if required output filter mode is defined
-		if(!(defined('OUTPUT_FILTER_MODE') && defined('OUTPUT_FILTER_MODE') && defined('OUTPUT_FILTER_MODE'))) {
-			return $match[0];
-		}
-		
-		$search = array('@', '.');
-		$replace = array(OUTPUT_FILTER_AT_REPLACEMENT ,OUTPUT_FILTER_DOT_REPLACEMENT);
-		
-		// check if the match contains the expected number of subpatterns (6|8)
-		if(count($match) == 8) {
-			/**
-				OUTPUT FILTER FOR EMAIL ADDRESSES EMBEDDED IN TEXT
-			**/
-			
-			// 1.. text mails only, 3.. text mails + mailto (no JS), 7 text mails + mailto (JS)
-			if(!in_array(OUTPUT_FILTER_MODE, array(1,3,7))) return $match[0];
-
-			// do not filter mail addresses included in input tags (<input ... value = "test@mail)
-			if (strpos($match[6], 'value') !== false) return $match[0];
-			
-			// filtering of non mailto email addresses enabled
-			return str_replace($search, $replace, $match[0]);
-				
-		} elseif(count($match) == 6) {
-			/**
-				OUTPUT FILTER FOR EMAIL ADDRESSES EMBEDDED IN MAILTO LINKS
-			**/
-
-			// 2.. mailto only (no JS), 3.. text mails + mailto (no JS), 6.. mailto only (JS), 7.. all filters active
-			if(!in_array(OUTPUT_FILTER_MODE, array(2,3,6,7))) return $match[0];
-			
-			// check if last part of the a href link: >xxxx</a> contains a email address we need to filter
-			$pattern = '#[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}#i';
-			if(preg_match_all($pattern, $match[5], $matches)) {
-				foreach($matches as $submatch) {
-					foreach($submatch as $value) {
-						// replace all . and all @ in email address parts by (dot) and (at) strings
-						$match[5] = str_replace($value, str_replace($search, $replace, $value), $match[5]);
-					}
-				}
-			}
-
-			// check if Javascript encryption routine is enabled
-			if(in_array(OUTPUT_FILTER_MODE, array(6,7))) {
-				/** USE JAVASCRIPT ENCRYPTION FOR MAILTO LINKS **/
-				
-				// extract possible class and id attribute from ahref link
-				preg_match('/class\s*?=\s*?("|\')(.*?)\1/ix', $match[0], $class_attr);
-				$class_attr = empty($class_attr) ? '' : 'class="' . $class_attr[2] . '" ';
-				preg_match('/id\s*?=\s*?("|\')(.*?)\1/ix', $match[0], $id_attr);
-				$id_attr = empty($id_attr) ? '' : 'id="' . $id_attr[2] . '" ';
-				
-				// preprocess mailto link parts for further usage
-				$search = array('@', '.', '_', '-'); $replace = array('F', 'Z', 'X', 'K');
-				$email_address = str_replace($search, $replace, strtolower($match[2]));
-				$email_subject = rawurlencode(html_entity_decode($match[3]));
-				
-				// create a random encryption key for the Caesar cipher
-				mt_srand((double)microtime()*1000000);	// (PHP < 4.2.0)
-				$shift = mt_rand(1, 25);
-				
-				// encrypt the email using an adapted Caesar cipher
-		  		$encrypted_email = "";
-				for($i = strlen($email_address) -1; $i > -1; $i--) {
-					if(preg_match('#[FZXK0-9]#', $email_address[$i], $characters)) {
-						$encrypted_email .= $email_address[$i];
-					} else {	
-						$encrypted_email .= chr((ord($email_address[$i]) -97 + $shift) % 26 + 97);
-					}
-				}
-				$encrypted_email .= chr($shift + 97);
-
-				// build the encrypted Javascript mailto link
-				$mailto_link  = "<a {$class_attr}{$id_attr}href=\"javascript:mdcr('$encrypted_email','$email_subject')\">" .$match[5] ."</a>";
-				
-				return $mailto_link;	
-
-			} else {
-				/** DO NOT USE JAVASCRIPT ENCRYPTION FOR MAILTO LINKS **/
-
-				// as minimum protection, replace replace @ in the mailto part by (at)
-				// dots are not transformed as this would transform my.name@domain.com into: my(dot)name(at)domain(dot)com
-				
-				// rebuild the mailto link from the subpatterns (at the missing characters " and </a>")
-				return $match[1] .str_replace('@', OUTPUT_FILTER_AT_REPLACEMENT, $match[2]) .$match[3] .'"' .$match[4] .$match[5] .'</a>';
-				// if you want to protect both, @ and dots, comment out the line above and remove the comment from the line below
-				// return $match[1] .str_replace($search, $replace, $match[2]) .$match[3] .'"' .$match[4] .$match[5] .'</a>';
-			}
-		
-		}
-		
-		// number of subpatterns do not match the requirements ... do nothing
-		return $match[0];
-	}		
-}
-
-?>
+<?php
+/**
+ *
+ * @category        modules
+ * @package         output_filter
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+// function to read the current filter settings
+if (!function_exists('get_output_filter_settings')) {
+	function get_output_filter_settings() {
+		global $database, $admin;
+		// connect to database and read out filter settings
+		$result = $database->query("SELECT * FROM " .TABLE_PREFIX ."mod_output_filter");
+		if($result && $result->numRows() > 0) {
+			// get all data
+			$data = $result->fetchRow();
+			$filter_settings['email_filter'] = $admin->strip_slashes($data['email_filter']);
+			$filter_settings['mailto_filter'] = $admin->strip_slashes($data['mailto_filter']);
+			$filter_settings['at_replacement'] = $admin->strip_slashes($data['at_replacement']);
+			$filter_settings['dot_replacement'] = $admin->strip_slashes($data['dot_replacement']);
+		} else {
+			// something went wrong, use default values
+			$filter_settings['email_filter'] = '0';
+			$filter_settings['mailto_filter'] = '0';
+			$filter_settings['at_replacement'] = '(at)';
+			$filter_settings['dot_replacement'] = '(dot)';
+		}
+		
+		// return array with filter settings
+		return $filter_settings;
+	}
+}
+
+// function to filter the output before displaying it on the frontend
+if (!function_exists('filter_frontend_output')) {
+	function filter_frontend_output($content) {
+		// get output filter settings from database
+		$filter_settings = get_output_filter_settings();
+		
+		// work out the defined output filter mode: possible output filter modes: [0], 1, 2, 3, 6, 7
+		// 2^0 * (0.. disable, 1.. enable) filtering of mail addresses in text
+		// 2^1 * (0.. disable, 1.. enable) filtering of mail addresses in mailto links
+		// 2^2 * (0.. disable, 1.. enable) Javascript mailto encryption (only if mailto filtering enabled)
+
+		// only filter output if we are supposed to
+		if($filter_settings['email_filter'] != '1' && $filter_settings['mailto_filter'] != '1'){
+			// nothing to do ...
+			return $content;
+		}
+
+		// check if non mailto mail addresses needs to be filtered
+		$output_filter_mode = ($filter_settings['email_filter'] == '1') ? 1 : 0;		// 0|1
+
+		// check if mailto mail addresses needs to be filtered
+		if($filter_settings['mailto_filter'] == '1') {
+			$output_filter_mode = $output_filter_mode + 2;								// 0|2
+
+			// check if Javascript mailto encryption is enabled (call register_frontend_functions in the template)
+           $search_pattern = '/<.*src=\".*\/mdcr.js.*>/iU';
+           if(preg_match($search_pattern, $content))
+           {
+            $output_filter_mode = $output_filter_mode + 4;       // 0|4
+           }
+/*
+			$search = '<script src="' .WB_URL .'/modules/output_filter/js/mdcr.js" type="text/javascript"></script>';
+			$search_droplet = '<script src="' .WB_URL .'/modules/droplets/js/mdcr.js" type="text/javascript"></script>';
+			if(strpos($content, $search) !== false || strpos($content, $search_droplet) !== false) {
+				$output_filter_mode = $output_filter_mode + 4;							// 0|4
+			}
+*/
+		}
+		
+		// define some constants so we do not call the database in the callback function again
+		define('OUTPUT_FILTER_MODE', (int) $output_filter_mode);
+		define('OUTPUT_FILTER_AT_REPLACEMENT', $filter_settings['at_replacement']);
+		define('OUTPUT_FILTER_DOT_REPLACEMENT', $filter_settings['dot_replacement']);
+		
+		// first search part to find all mailto email addresses
+		$pattern = '#(<a[^<]*href\s*?=\s*?"\s*?mailto\s*?:\s*?)([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})([^"]*?)"([^>]*>)(.*?)</a>';
+		// second part to find all non mailto email addresses
+		$pattern .= '|(value\s*=\s*"|\')??\b([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})\b#i';
+		/*
+		Sub 1:\b(<a.[^<]*href\s*?=\s*?"\s*?mailto\s*?:\s*?)			-->	"<a id="yyy" class="xxx" href = " mailto :" ignoring white spaces
+		Sub 2:([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})			-->	the email address in the mailto: part of the mail link
+		Sub 3:([^"]*?)"												--> possible ?Subject&cc... stuff attached to the mail address
+		Sub 4:([^>]*>)												--> all class or id statements after the mailto but before closing ..>
+		Sub 5:(.*?)</a>\b											--> the mailto text; all characters between >xxxxx</a>
+		Sub 6:|\b([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})\b		--> email addresses which may appear in the text (require word boundaries)
+		*/
+			
+		// find all email addresses embedded in the content and filter them using a callback function
+		$content = preg_replace_callback($pattern, 'filter_mail_addresses', $content);
+		return $content;
+	}
+}		
+
+
+// function to filter mail addresses embedded in text or mailto links before outputing them on the frontend
+if (!function_exists('filter_mail_addresses')) {
+	function filter_mail_addresses($match) { 
+		
+		// check if required output filter mode is defined
+		if(!(defined('OUTPUT_FILTER_MODE') && defined('OUTPUT_FILTER_MODE') && defined('OUTPUT_FILTER_MODE'))) {
+			return $match[0];
+		}
+		
+		$search = array('@', '.');
+		$replace = array(OUTPUT_FILTER_AT_REPLACEMENT ,OUTPUT_FILTER_DOT_REPLACEMENT);
+		
+		// check if the match contains the expected number of subpatterns (6|8)
+		if(count($match) == 8) {
+			/**
+				OUTPUT FILTER FOR EMAIL ADDRESSES EMBEDDED IN TEXT
+			**/
+			
+			// 1.. text mails only, 3.. text mails + mailto (no JS), 7 text mails + mailto (JS)
+			if(!in_array(OUTPUT_FILTER_MODE, array(1,3,7))) return $match[0];
+
+			// do not filter mail addresses included in input tags (<input ... value = "test@mail)
+			if (strpos($match[6], 'value') !== false) return $match[0];
+			
+			// filtering of non mailto email addresses enabled
+			return str_replace($search, $replace, $match[0]);
+				
+		} elseif(count($match) == 6) {
+			/**
+				OUTPUT FILTER FOR EMAIL ADDRESSES EMBEDDED IN MAILTO LINKS
+			**/
+
+			// 2.. mailto only (no JS), 3.. text mails + mailto (no JS), 6.. mailto only (JS), 7.. all filters active
+			if(!in_array(OUTPUT_FILTER_MODE, array(2,3,6,7))) return $match[0];
+			
+			// check if last part of the a href link: >xxxx</a> contains a email address we need to filter
+			$pattern = '#[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}#i';
+			if(preg_match_all($pattern, $match[5], $matches)) {
+				foreach($matches as $submatch) {
+					foreach($submatch as $value) {
+						// replace all . and all @ in email address parts by (dot) and (at) strings
+						$match[5] = str_replace($value, str_replace($search, $replace, $value), $match[5]);
+					}
+				}
+			}
+
+			// check if Javascript encryption routine is enabled
+			if(in_array(OUTPUT_FILTER_MODE, array(6,7))) {
+				/** USE JAVASCRIPT ENCRYPTION FOR MAILTO LINKS **/
+				
+				// extract possible class and id attribute from ahref link
+				preg_match('/class\s*?=\s*?("|\')(.*?)\1/ix', $match[0], $class_attr);
+				$class_attr = empty($class_attr) ? '' : 'class="' . $class_attr[2] . '" ';
+				preg_match('/id\s*?=\s*?("|\')(.*?)\1/ix', $match[0], $id_attr);
+				$id_attr = empty($id_attr) ? '' : 'id="' . $id_attr[2] . '" ';
+				
+				// preprocess mailto link parts for further usage
+				$search = array('@', '.', '_', '-'); $replace = array('F', 'Z', 'X', 'K');
+				$email_address = str_replace($search, $replace, strtolower($match[2]));
+				$email_subject = rawurlencode(html_entity_decode($match[3]));
+				
+				// create a random encryption key for the Caesar cipher
+				mt_srand((double)microtime()*1000000);	// (PHP < 4.2.0)
+				$shift = mt_rand(1, 25);
+				
+				// encrypt the email using an adapted Caesar cipher
+		  		$encrypted_email = "";
+				for($i = strlen($email_address) -1; $i > -1; $i--) {
+					if(preg_match('#[FZXK0-9]#', $email_address[$i], $characters)) {
+						$encrypted_email .= $email_address[$i];
+					} else {	
+						$encrypted_email .= chr((ord($email_address[$i]) -97 + $shift) % 26 + 97);
+					}
+				}
+				$encrypted_email .= chr($shift + 97);
+
+				// build the encrypted Javascript mailto link
+				$mailto_link  = "<a {$class_attr}{$id_attr}href=\"javascript:mdcr('$encrypted_email','$email_subject')\">" .$match[5] ."</a>";
+				
+				return $mailto_link;	
+
+			} else {
+				/** DO NOT USE JAVASCRIPT ENCRYPTION FOR MAILTO LINKS **/
+
+				// as minimum protection, replace replace @ in the mailto part by (at)
+				// dots are not transformed as this would transform my.name@domain.com into: my(dot)name(at)domain(dot)com
+				
+				// rebuild the mailto link from the subpatterns (at the missing characters " and </a>")
+				return $match[1] .str_replace('@', OUTPUT_FILTER_AT_REPLACEMENT, $match[2]) .$match[3] .'"' .$match[4] .$match[5] .'</a>';
+				// if you want to protect both, @ and dots, comment out the line above and remove the comment from the line below
+				// return $match[1] .str_replace($search, $replace, $match[2]) .$match[3] .'"' .$match[4] .$match[5] .'</a>';
+			}
+		
+		}
+		
+		// number of subpatterns do not match the requirements ... do nothing
+		return $match[0];
+	}		
+}
+
+?>
Index: branches/2.8.x/wb/modules/output_filter/tool.php
===================================================================
--- branches/2.8.x/wb/modules/output_filter/tool.php	(revision 1419)
+++ branches/2.8.x/wb/modules/output_filter/tool.php	(revision 1420)
@@ -1,113 +1,113 @@
-<?php
-/**
- *
- * @category        modules
- * @package         output_filter
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// prevent this file from being accessed directly
-if(!defined('WB_PATH')) die(header('Location: ../index.php'));
-
-// check if module language file exists for the language set by the user (e.g. DE, EN)
-$MOD_MAIL_FILTER['WARNING']	= '<p style="color: red; line-height:1.5em;"><strong>Warning: </strong>This function is now available as a Droplet. The next major release of website baker will not include this filter anymore. Please concider using the <a href="?tool=droplets">Droplet</a> [[EmailFilter]]</p>';
-if(!file_exists(WB_PATH .'/modules/output_filter/languages/'.LANGUAGE .'.php')) {
-	// no module language file exists for the language set by the user, include default module language file EN.php
-	require_once(WB_PATH .'/modules/output_filter/languages/EN.php');
-} else {
-	// a module language file exists for the language defined by the user, load it
-	require_once(WB_PATH .'/modules/output_filter/languages/'.LANGUAGE .'.php');
-}
-// check if data was submitted
-if(isset($_POST['save_settings'])) {
-	
-	if (!$admin->checkFTAN())
-	{
-		$admin->print_error($MESSAGE['GENERIC_SECURITY_ACCESS'], ADMIN_URL);
-		exit();
-	}
-	// get overall output filter settings
-	$email_filter = (isset($_POST['email_filter']) && $_POST['email_filter'] == '1') ? '1' : '0';
-	$mailto_filter = (isset($_POST['mailto_filter']) && $_POST['mailto_filter'] == '1') ? '1' : '0';
-	
-	// get email replacement settings
-	$at_replacement = isset($_POST['at_replacement']) ?strip_tags($_POST['at_replacement']) : '';
-	$at_replacement = (strlen(trim($at_replacement)) > 0) ? $admin->add_slashes($at_replacement) : '(at)';
-	$dot_replacement = isset($_POST['dot_replacement']) ?strip_tags($_POST['dot_replacement']) : '';
-	$dot_replacement = (strlen(trim($dot_replacement)) > 0) ? $admin->add_slashes($dot_replacement) : '(dot)';
-	
-	// update database settings
-	$database->query("UPDATE " .TABLE_PREFIX ."mod_output_filter SET email_filter = '$email_filter', 
-		mailto_filter = '$mailto_filter', at_replacement = '$at_replacement', dot_replacement = '$dot_replacement'");
-
-	// check if there is a database error, otherwise say successful
-	if($database->is_error()) {
-		$admin->print_error($database->get_error(), $js_back);
-	} else {
-		$admin->print_success($MESSAGE['PAGES']['SAVED'], ADMIN_URL.'/admintools/tool.php?tool=output_filter');
-	}
-
-} else {
-	// write out heading
-	echo '<h2>' .$MOD_MAIL_FILTER['HEADING'] .'</h2>';
-
-	// include filter functions
-	require_once(WB_PATH .'/modules/output_filter/filter-routines.php');
-	
-	// read the mail filter settings from the database 
-	$data = get_output_filter_settings();
-	
-	// output the form with values from the database
-	echo '<p>' .$MOD_MAIL_FILTER['HOWTO'] .'</p>';
-	echo $MOD_MAIL_FILTER['WARNING'];
-?>
-<form name="store_settings" action="<?php echo $_SERVER['REQUEST_URI'];?>" method="post">
-<?php echo $admin->getFTAN(); ?>
-	<table width="98%" cellspacing="0" cellpadding="5px" class="row_a">
-	<tr><td colspan="2"><strong><?php echo $MOD_MAIL_FILTER['BASIC_CONF'];?>:</strong></td></tr>
-	<tr>
-		<td width="35%"><?php echo $MOD_MAIL_FILTER['EMAIL_FILTER'];?>:</td>
-		<td>
-			<input type="radio" <?php echo ($data['email_filter']=='1') ?'checked="checked"' :'';?>
-				name="email_filter" value="1"><?php echo $MOD_MAIL_FILTER['ENABLED'];?>
-			<input type="radio" <?php echo (($data['email_filter'])=='0') ?'checked="checked"' :'';?>
-				name="email_filter" value="0"><?php echo $MOD_MAIL_FILTER['DISABLED'];?>
-		</td>
-	</tr>
-	<tr>
-		<td><?php echo $MOD_MAIL_FILTER['MAILTO_FILTER'];?>:</td>
-		<td>
-			<input type="radio" <?php echo ($data['mailto_filter']=='1') ?'checked="checked"' :'';?>
-				name="mailto_filter" value="1"><?php echo $MOD_MAIL_FILTER['ENABLED'];?>
-			<input type="radio" <?php echo (($data['mailto_filter'])=='0') ?'checked="checked"' :'';?>
-				name="mailto_filter" value="0"><?php echo $MOD_MAIL_FILTER['DISABLED'];?>
-		</td>
-	</tr>
-	<tr><td colspan="2"><br /><strong><?php echo $MOD_MAIL_FILTER['REPLACEMENT_CONF'];?>:</strong></td></tr>
-	<tr>
-		<td><?php echo $MOD_MAIL_FILTER['AT_REPLACEMENT'];?>:</td>
-		<td><input type="text" style="width: 160px" value="<?php echo $data['at_replacement'];?>" 
-			name="at_replacement"/></td>
-	</tr>
-	<tr>
-		<td><?php echo $MOD_MAIL_FILTER['DOT_REPLACEMENT'];?>:</td>
-		<td><input type="text" style="width: 160px" value="<?php echo $data['dot_replacement'];?>" 
-			name="dot_replacement"/></td>
-	</tr>
-	</table>
-	<input type="submit" name="save_settings" style="margin-top:10px; width:140px;" value="<?php echo $TEXT['SAVE']; ?>" />
-</form>
-<?php
-}
-
-?>
+<?php
+/**
+ *
+ * @category        modules
+ * @package         output_filter
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+// check if module language file exists for the language set by the user (e.g. DE, EN)
+$MOD_MAIL_FILTER['WARNING']	= '<p style="color: red; line-height:1.5em;"><strong>Warning: </strong>This function is now available as a Droplet. The next major release of website baker will not include this filter anymore. Please concider using the <a href="?tool=droplets">Droplet</a> [[EmailFilter]]</p>';
+if(!file_exists(WB_PATH .'/modules/output_filter/languages/'.LANGUAGE .'.php')) {
+	// no module language file exists for the language set by the user, include default module language file EN.php
+	require_once(WB_PATH .'/modules/output_filter/languages/EN.php');
+} else {
+	// a module language file exists for the language defined by the user, load it
+	require_once(WB_PATH .'/modules/output_filter/languages/'.LANGUAGE .'.php');
+}
+// check if data was submitted
+if(isset($_POST['save_settings'])) {
+	
+	if (!$admin->checkFTAN())
+	{
+		$admin->print_error($MESSAGE['GENERIC_SECURITY_ACCESS'], ADMIN_URL);
+		exit();
+	}
+	// get overall output filter settings
+	$email_filter = (isset($_POST['email_filter']) && $_POST['email_filter'] == '1') ? '1' : '0';
+	$mailto_filter = (isset($_POST['mailto_filter']) && $_POST['mailto_filter'] == '1') ? '1' : '0';
+	
+	// get email replacement settings
+	$at_replacement = isset($_POST['at_replacement']) ?strip_tags($_POST['at_replacement']) : '';
+	$at_replacement = (strlen(trim($at_replacement)) > 0) ? $admin->add_slashes($at_replacement) : '(at)';
+	$dot_replacement = isset($_POST['dot_replacement']) ?strip_tags($_POST['dot_replacement']) : '';
+	$dot_replacement = (strlen(trim($dot_replacement)) > 0) ? $admin->add_slashes($dot_replacement) : '(dot)';
+	
+	// update database settings
+	$database->query("UPDATE " .TABLE_PREFIX ."mod_output_filter SET email_filter = '$email_filter', 
+		mailto_filter = '$mailto_filter', at_replacement = '$at_replacement', dot_replacement = '$dot_replacement'");
+
+	// check if there is a database error, otherwise say successful
+	if($database->is_error()) {
+		$admin->print_error($database->get_error(), $js_back);
+	} else {
+		$admin->print_success($MESSAGE['PAGES']['SAVED'], ADMIN_URL.'/admintools/tool.php?tool=output_filter');
+	}
+
+} else {
+	// write out heading
+	echo '<h2>' .$MOD_MAIL_FILTER['HEADING'] .'</h2>';
+
+	// include filter functions
+	require_once(WB_PATH .'/modules/output_filter/filter-routines.php');
+	
+	// read the mail filter settings from the database 
+	$data = get_output_filter_settings();
+	
+	// output the form with values from the database
+	echo '<p>' .$MOD_MAIL_FILTER['HOWTO'] .'</p>';
+	echo $MOD_MAIL_FILTER['WARNING'];
+?>
+<form name="store_settings" action="<?php echo $_SERVER['REQUEST_URI'];?>" method="post">
+<?php echo $admin->getFTAN(); ?>
+	<table width="98%" cellspacing="0" cellpadding="5px" class="row_a">
+	<tr><td colspan="2"><strong><?php echo $MOD_MAIL_FILTER['BASIC_CONF'];?>:</strong></td></tr>
+	<tr>
+		<td width="35%"><?php echo $MOD_MAIL_FILTER['EMAIL_FILTER'];?>:</td>
+		<td>
+			<input type="radio" <?php echo ($data['email_filter']=='1') ?'checked="checked"' :'';?>
+				name="email_filter" value="1"><?php echo $MOD_MAIL_FILTER['ENABLED'];?>
+			<input type="radio" <?php echo (($data['email_filter'])=='0') ?'checked="checked"' :'';?>
+				name="email_filter" value="0"><?php echo $MOD_MAIL_FILTER['DISABLED'];?>
+		</td>
+	</tr>
+	<tr>
+		<td><?php echo $MOD_MAIL_FILTER['MAILTO_FILTER'];?>:</td>
+		<td>
+			<input type="radio" <?php echo ($data['mailto_filter']=='1') ?'checked="checked"' :'';?>
+				name="mailto_filter" value="1"><?php echo $MOD_MAIL_FILTER['ENABLED'];?>
+			<input type="radio" <?php echo (($data['mailto_filter'])=='0') ?'checked="checked"' :'';?>
+				name="mailto_filter" value="0"><?php echo $MOD_MAIL_FILTER['DISABLED'];?>
+		</td>
+	</tr>
+	<tr><td colspan="2"><br /><strong><?php echo $MOD_MAIL_FILTER['REPLACEMENT_CONF'];?>:</strong></td></tr>
+	<tr>
+		<td><?php echo $MOD_MAIL_FILTER['AT_REPLACEMENT'];?>:</td>
+		<td><input type="text" style="width: 160px" value="<?php echo $data['at_replacement'];?>" 
+			name="at_replacement"/></td>
+	</tr>
+	<tr>
+		<td><?php echo $MOD_MAIL_FILTER['DOT_REPLACEMENT'];?>:</td>
+		<td><input type="text" style="width: 160px" value="<?php echo $data['dot_replacement'];?>" 
+			name="dot_replacement"/></td>
+	</tr>
+	</table>
+	<input type="submit" name="save_settings" style="margin-top:10px; width:140px;" value="<?php echo $TEXT['SAVE']; ?>" />
+</form>
+<?php
+}
+
+?>
Index: branches/2.8.x/wb/modules/output_filter/install.php
===================================================================
--- branches/2.8.x/wb/modules/output_filter/install.php	(revision 1419)
+++ branches/2.8.x/wb/modules/output_filter/install.php	(revision 1420)
@@ -1,37 +1,37 @@
-<?php
-/**
- *
- * @category        modules
- * @package         output_filter
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// prevent this file from being accessed directly
-if(!defined('WB_PATH')) die(header('Location: ../index.php'));
-
-$table = TABLE_PREFIX .'mod_output_filter';
-$database->query("DROP TABLE IF EXISTS `$table`");
-
-$database->query("CREATE TABLE `$table` (
-	`email_filter` VARCHAR(1) NOT NULL DEFAULT '0',
-	`mailto_filter` VARCHAR(1) NOT NULL DEFAULT '0',
-	`at_replacement` VARCHAR(255) NOT NULL DEFAULT '(at)',
-	`dot_replacement` VARCHAR(255) NOT NULL DEFAULT '(dot)'
-	)"
-);
-
-// add default values to the module table
-$database->query("INSERT INTO ".TABLE_PREFIX
-	."mod_output_filter (email_filter, mailto_filter, at_replacement, dot_replacement) VALUES ('0', '0', '(at)', '(dot)')");
-
+<?php
+/**
+ *
+ * @category        modules
+ * @package         output_filter
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+$table = TABLE_PREFIX .'mod_output_filter';
+$database->query("DROP TABLE IF EXISTS `$table`");
+
+$database->query("CREATE TABLE `$table` (
+	`email_filter` VARCHAR(1) NOT NULL DEFAULT '0',
+	`mailto_filter` VARCHAR(1) NOT NULL DEFAULT '0',
+	`at_replacement` VARCHAR(255) NOT NULL DEFAULT '(at)',
+	`dot_replacement` VARCHAR(255) NOT NULL DEFAULT '(dot)'
+	)"
+);
+
+// add default values to the module table
+$database->query("INSERT INTO ".TABLE_PREFIX
+	."mod_output_filter (email_filter, mailto_filter, at_replacement, dot_replacement) VALUES ('0', '0', '(at)', '(dot)')");
+
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/show_menu2/include.php
===================================================================
--- branches/2.8.x/wb/modules/show_menu2/include.php	(revision 1419)
+++ branches/2.8.x/wb/modules/show_menu2/include.php	(revision 1420)
@@ -16,6 +16,9 @@
  *
  */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
 define('SM2_ROOT',          -1000);
 define('SM2_CURR',          -2000);
 define('SM2_ALLMENU',          -1);
Index: branches/2.8.x/wb/modules/show_menu2/legacy.php
===================================================================
--- branches/2.8.x/wb/modules/show_menu2/legacy.php	(revision 1419)
+++ branches/2.8.x/wb/modules/show_menu2/legacy.php	(revision 1420)
@@ -64,6 +64,9 @@
  * 10. $current_class: The class of the currently viewed page
  * 11. $parent:    (used internally) The page_id of the menu's root node, defaults is '0' (root level)
  */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
  
 class SM2_ShowMenuFormatter
 {
Index: branches/2.8.x/wb/modules/show_menu2/install.php
===================================================================
--- branches/2.8.x/wb/modules/show_menu2/install.php	(revision 1419)
+++ branches/2.8.x/wb/modules/show_menu2/install.php	(revision 1420)
@@ -17,5 +17,8 @@
  *
  */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
+
 ?>
Index: branches/2.8.x/wb/modules/show_menu2/upgrade.php
===================================================================
--- branches/2.8.x/wb/modules/show_menu2/upgrade.php	(revision 1419)
+++ branches/2.8.x/wb/modules/show_menu2/upgrade.php	(revision 1420)
@@ -17,5 +17,7 @@
  *
  */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 ?>
Index: branches/2.8.x/wb/modules/code/view.php
===================================================================
--- branches/2.8.x/wb/modules/code/view.php	(revision 1419)
+++ branches/2.8.x/wb/modules/code/view.php	(revision 1420)
@@ -23,6 +23,8 @@
 
 */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 // Get content
 $get_content = $database->query("SELECT content FROM ".TABLE_PREFIX."mod_code WHERE section_id = '$section_id'");
 $fetch_content = $get_content->fetchRow();
Index: branches/2.8.x/wb/modules/code/delete.php
===================================================================
--- branches/2.8.x/wb/modules/code/delete.php	(revision 1419)
+++ branches/2.8.x/wb/modules/code/delete.php	(revision 1420)
@@ -22,6 +22,8 @@
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 */
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 
 // Delete record from the database
 $database->query("DELETE FROM ".TABLE_PREFIX."mod_code WHERE section_id = '$section_id'");
Index: branches/2.8.x/wb/modules/code/modify.php
===================================================================
--- branches/2.8.x/wb/modules/code/modify.php	(revision 1419)
+++ branches/2.8.x/wb/modules/code/modify.php	(revision 1420)
@@ -1,50 +1,52 @@
-<?php
-/**
- *
- * @category        modules
- * @package         code
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// Setup template object
-$template = new Template(WB_PATH.'/modules/code');
-$template->set_file('page', 'htt/modify.htt');
-$template->set_block('page', 'main_block', 'main');
-
-// Get page content
-$query = "SELECT content FROM ".TABLE_PREFIX."mod_code WHERE section_id = '$section_id'";
-$get_content = $database->query($query);
-$content = $get_content->fetchRow();
-$content = htmlspecialchars($content['content']);
-
-// Insert vars
-$template->set_var(
-	array(
-		'PAGE_ID'				=> $page_id,
-		'SECTION_ID'			=> $section_id,
-		'REGISTER_EDIT_AREA'	=> function_exists('registerEditArea') ? registerEditArea('content'.$section_id, 'php', false) : '',
-		'WB_URL'				=> WB_URL,
-		'CONTENT'				=> $content,
-		'TEXT_SAVE'				=> $TEXT['SAVE'],
-		'TEXT_CANCEL'			=> $TEXT['CANCEL'],
-		'SECTION'				=> $section_id,
-		'FTAN'					=> $admin->getFTAN()
-	)
-);
-
-// Parse template object
-$template->set_unknowns('keep');
-$template->parse('main', 'main_block', false);
-$template->pparse('output', 'page', false);
-
+<?php
+/**
+ *
+ * @category        modules
+ * @package         code
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+// Setup template object
+$template = new Template(WB_PATH.'/modules/code');
+$template->set_file('page', 'htt/modify.htt');
+$template->set_block('page', 'main_block', 'main');
+
+// Get page content
+$query = "SELECT content FROM ".TABLE_PREFIX."mod_code WHERE section_id = '$section_id'";
+$get_content = $database->query($query);
+$content = $get_content->fetchRow();
+$content = htmlspecialchars($content['content']);
+
+// Insert vars
+$template->set_var(
+	array(
+		'PAGE_ID'				=> $page_id,
+		'SECTION_ID'			=> $section_id,
+		'REGISTER_EDIT_AREA'	=> function_exists('registerEditArea') ? registerEditArea('content'.$section_id, 'php', false) : '',
+		'WB_URL'				=> WB_URL,
+		'CONTENT'				=> $content,
+		'TEXT_SAVE'				=> $TEXT['SAVE'],
+		'TEXT_CANCEL'			=> $TEXT['CANCEL'],
+		'SECTION'				=> $section_id,
+		'FTAN'					=> $admin->getFTAN()
+	)
+);
+
+// Parse template object
+$template->set_unknowns('keep');
+$template->parse('main', 'main_block', false);
+$template->pparse('output', 'page', false);
+
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/code/add.php
===================================================================
--- branches/2.8.x/wb/modules/code/add.php	(revision 1419)
+++ branches/2.8.x/wb/modules/code/add.php	(revision 1420)
@@ -23,6 +23,8 @@
 
 */
 
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
 // Insert an extra row into the database
 $database->query("INSERT INTO ".TABLE_PREFIX."mod_code (page_id,section_id) VALUES ('$page_id','$section_id')");
 
Index: branches/2.8.x/wb/modules/fckeditor/class.cssparser.php
===================================================================
--- branches/2.8.x/wb/modules/fckeditor/class.cssparser.php	(revision 1419)
+++ branches/2.8.x/wb/modules/fckeditor/class.cssparser.php	(revision 1420)
@@ -1,304 +1,306 @@
-<?php
-
-// $Id$
-
-/*
-
- Website Baker Project <http://www.websitebaker.org/>
- Copyright (C) 2004-2009, Ryan Djurovich
-
- Website Baker is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- Website Baker is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Website Baker; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-/*
- * Class to parse css information.
- *
- * See the readme file : http://www.phpclasses.org/browse/file/4685.html
- *
- * $Id$
- *
- * @author http://www.phpclasses.org/browse/package/1289.html
- * @package PhpGedView
- * @subpackage Charts
- *
- * added function GetXML to the cssparser class (Christian Sommer, 2007)
- *
- */
-
-class cssparser {
-	var $css;
-	var $html;
-  
-	function cssparser($html = true) {
-		// Register "destructor"
-		register_shutdown_function(array(&$this, "finalize"));
-		$this->html = ($html != false);
-		$this->Clear();
-	}
-  
-	function finalize() {
-		unset($this->css);
-	}
-  
-	function Clear() {
-		unset($this->css);
-		$this->css = array();
-		if($this->html) {
-			$this->Add("ADDRESS", "");
-			$this->Add("APPLET", "");
-			$this->Add("AREA", "");
-			$this->Add("A", "");
-			$this->Add("A:visited", "");
-			$this->Add("BASE", "");
-			$this->Add("BASEFONT", "");
-			$this->Add("BIG", "");
-			$this->Add("BLOCKQUOTE", "");
-			$this->Add("BODY", "");
-			$this->Add("BR", "");
-			$this->Add("B", "");
-			$this->Add("CAPTION", "");
-			$this->Add("CENTER", "");
-			$this->Add("CITE", "");
-			$this->Add("CODE", "");
-			$this->Add("DD", "");
-			$this->Add("DFN", "");
-			$this->Add("DIR", "");
-			$this->Add("DIV", "");
-			$this->Add("DL", "");
-			$this->Add("DT", "");
-			$this->Add("EM", "");
-			$this->Add("FONT", "");
-			$this->Add("FORM", "");
-			$this->Add("H1", "");
-			$this->Add("H2", "");
-			$this->Add("H3", "");
-			$this->Add("H4", "");
-			$this->Add("H5", "");
-			$this->Add("H6", "");
-			$this->Add("HEAD", "");
-			$this->Add("HR", "");
-			$this->Add("HTML", "");
-			$this->Add("IMG", "");
-			$this->Add("INPUT", "");
-			$this->Add("ISINDEX", "");
-			$this->Add("I", "");
-			$this->Add("KBD", "");
-			$this->Add("LINK", "");
-			$this->Add("LI", "");
-			$this->Add("MAP", "");
-			$this->Add("MENU", "");
-			$this->Add("META", "");
-			$this->Add("OL", "");
-			$this->Add("OPTION", "");
-			$this->Add("PARAM", "");
-			$this->Add("PRE", "");
-			$this->Add("P", "");
-			$this->Add("SAMP", "");
-			$this->Add("SCRIPT", "");
-			$this->Add("SELECT", "");
-			$this->Add("SMALL", "");
-			$this->Add("STRIKE", "");
-			$this->Add("STRONG", "");
-			$this->Add("STYLE", "");
-			$this->Add("SUB", "");
-			$this->Add("SUP", "");
-			$this->Add("TABLE", "");
-			$this->Add("TD", "");
-			$this->Add("TEXTAREA", "");
-			$this->Add("TH", "");
-			$this->Add("TITLE", "");
-			$this->Add("TR", "");
-			$this->Add("TT", "");
-			$this->Add("UL", "");
-			$this->Add("U", "");
-			$this->Add("VAR", "");
-		}
-	}
-  
-	function SetHTML($html) {
-		$this->html = ($html != false);
-	}
-  
-	function Add($key, $codestr) {
-		$key = strtolower($key);
-		//    $codestr = strtolower($codestr);
-		if(!isset($this->css[$key])) {
-			$this->css[$key] = array();
-		}
-		$codes = explode(";",$codestr);
-		if(count($codes) > 0) {
-			foreach($codes as $code) {
-				$code = trim($code);
-				@list($codekey, $codevalue) = explode(":",$code);
-				if(strlen($codekey) > 0) {
-					$this->css[$key][trim($codekey)] = trim($codevalue);
-				}
-			}
-		}
-	}
-  
-	function Get($key, $property) {
-		$key = strtolower($key);
-		//    $property = strtolower($property);
-		@list($tag, $subtag) = explode(":",$key);
-		@list($tag, $class) = explode(".",$tag);
-		@list($tag, $id) = explode("#",$tag);
-		$result = "";
-		foreach($this->css as $_tag => $value) {
-			@list($_tag, $_subtag) = explode(":",$_tag);
-			@list($_tag, $_class) = explode(".",$_tag);
-			@list($_tag, $_id) = explode("#",$_tag);
-            $tagmatch = (strcmp($tag, $_tag) == 0) | (strlen($_tag) == 0);
-			$subtagmatch = (strcmp($subtag, $_subtag) == 0) | (strlen($_subtag) == 0);
-			$classmatch = (strcmp($class, $_class) == 0) | (strlen($_class) == 0);
-			$idmatch = (strcmp($id, $_id) == 0);
-            if($tagmatch & $subtagmatch & $classmatch & $idmatch) {
-				$temp = $_tag;
-				if((strlen($temp) > 0) & (strlen($_class) > 0)) {
-					$temp .= ".".$_class;
-				}
-				elseif(strlen($temp) == 0) {
-					$temp = ".".$_class;
-				}
-				if((strlen($temp) > 0) & (strlen($_subtag) > 0)) {
-					$temp .= ":".$_subtag;
-				}
-				elseif(strlen($temp) == 0) {
-					$temp = ":".$_subtag;
-				}
-				if(isset($this->css[$temp][$property])) {
-					$result = $this->css[$temp][$property];
-				}
-			}
-		}
-		return $result;
-	}
-  
-	function GetSection($key) {
-		$key = strtolower($key);
-        @list($tag, $subtag) = explode(":",$key);
-		@list($tag, $class) = explode(".",$tag);
-		@list($tag, $id) = explode("#",$tag);
-		$result = array();
-		foreach($this->css as $_tag => $value) {
-			@list($_tag, $_subtag) = explode(":",$_tag);
-			@list($_tag, $_class) = explode(".",$_tag);
-			@list($_tag, $_id) = explode("#",$_tag);
-			$tagmatch = (strcmp($tag, $_tag) == 0) | (strlen($_tag) == 0);
-			$subtagmatch = (strcmp($subtag, $_subtag) == 0) | (strlen($_subtag) == 0);
-			$classmatch = (strcmp($class, $_class) == 0) | (strlen($_class) == 0);
-			$idmatch = (strcmp($id, $_id) == 0);
-			if($tagmatch & $subtagmatch & $classmatch & $idmatch) {
-				$temp = $_tag;
-				if((strlen($temp) > 0) & (strlen($_class) > 0)) {
-					$temp .= ".".$_class;
-				}
-				elseif(strlen($temp) == 0) {
-					$temp = ".".$_class;
-				}
-				if((strlen($temp) > 0) & (strlen($_subtag) > 0)) {
-					$temp .= ":".$_subtag;
-				}
-				elseif(strlen($temp) == 0) {
-					$temp = ":".$_subtag;
-				}	
-				foreach($this->css[$temp] as $property => $value) {
-					$result[$property] = $value;
-				}
-			}
-		}
-		return $result;
-	}
-  
-	function ParseStr($str) {
-		$this->Clear();
-		// Remove comments
-		$str = preg_replace("/\/\*(.*)?\*\//Usi", "", $str);
-		// Parse this damn csscode
-		$parts = explode("}",$str);
-		if(count($parts) > 0) {
-			foreach($parts as $part) {
-				@list($keystr,$codestr) = explode("{",$part);
-				$keys = explode(",",trim($keystr));
-				if(count($keys) > 0) {
-					foreach($keys as $key) {
-						if(strlen($key) > 0) {
-							$key = str_replace("\n", "", $key);
-							$key = str_replace("\\", "", $key);
-							$this->Add($key, trim($codestr));
-						}
-					}
-				}
-			}
-		}
-		//
-		return (count($this->css) > 0);
-	}
-  
-	function Parse($filename) {
-		$this->Clear();
-		if(file_exists($filename)) {
-			return $this->ParseStr(file_get_contents($filename));
-		}
-		else {
-			return false;
-		}
-	}
-	
-	function GetCSS() {
-		$result = "";
-		foreach($this->css as $key => $values) {
-			$result .= $key." {\n";
-			foreach($values as $key => $value) {
-				$result .= "  $key: $value;\n";
-			}
-			$result .= "}\n\n";
-		}
-		return $result;
-	}
-
-	function GetXML() {
-		// Construction of "fckstyles.xml" for FCKeditor
-		$styles = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"."\n";
-		$styles .= '<Styles>'."\n";
-		foreach ($this->css as $key => $value) {
-			// skip all CSS that are a combination of CSS
-			// skip CSS that are binded on an EVENT
-			if (strpos($key, " ") === false && strpos($key, ":") === false) {
-				$pieces = explode(".", $key, 2);
-				if (strcmp($pieces[0], "") != 0) {
-					continue;
-				} else {
-					$style_elem = "span";
-				}
-				if (strcmp($pieces[1], "") != 0) {
-					$style_class_name = $pieces[1];
-				} else {
-					$style_class_name = $pieces[0];
-				}
-				$styles .= '<Style name="'.$style_class_name.'" element="'.$style_elem.'"';
-				if (strcmp($style_class_name, $style_elem) != 0) {
-					$styles .= '>'."\n".'<Attribute name="class" value="'.$style_class_name.'" />'."\n".'</Style>'."\n";
-				} else {
-					$styles .= '/>'."\n";
-				}
-			}
-		}
-		$styles .= '</Styles>'."\n";
-		return trim($styles);
-	}
-}
+<?php
+
+// $Id$
+
+/*
+
+ Website Baker Project <http://www.websitebaker.org/>
+ Copyright (C) 2004-2009, Ryan Djurovich
+
+ Website Baker is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Website Baker is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Website Baker; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+/*
+ * Class to parse css information.
+ *
+ * See the readme file : http://www.phpclasses.org/browse/file/4685.html
+ *
+ * $Id$
+ *
+ * @author http://www.phpclasses.org/browse/package/1289.html
+ * @package PhpGedView
+ * @subpackage Charts
+ *
+ * added function GetXML to the cssparser class (Christian Sommer, 2007)
+ *
+ */
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+class cssparser {
+	var $css;
+	var $html;
+  
+	function cssparser($html = true) {
+		// Register "destructor"
+		register_shutdown_function(array(&$this, "finalize"));
+		$this->html = ($html != false);
+		$this->Clear();
+	}
+  
+	function finalize() {
+		unset($this->css);
+	}
+  
+	function Clear() {
+		unset($this->css);
+		$this->css = array();
+		if($this->html) {
+			$this->Add("ADDRESS", "");
+			$this->Add("APPLET", "");
+			$this->Add("AREA", "");
+			$this->Add("A", "");
+			$this->Add("A:visited", "");
+			$this->Add("BASE", "");
+			$this->Add("BASEFONT", "");
+			$this->Add("BIG", "");
+			$this->Add("BLOCKQUOTE", "");
+			$this->Add("BODY", "");
+			$this->Add("BR", "");
+			$this->Add("B", "");
+			$this->Add("CAPTION", "");
+			$this->Add("CENTER", "");
+			$this->Add("CITE", "");
+			$this->Add("CODE", "");
+			$this->Add("DD", "");
+			$this->Add("DFN", "");
+			$this->Add("DIR", "");
+			$this->Add("DIV", "");
+			$this->Add("DL", "");
+			$this->Add("DT", "");
+			$this->Add("EM", "");
+			$this->Add("FONT", "");
+			$this->Add("FORM", "");
+			$this->Add("H1", "");
+			$this->Add("H2", "");
+			$this->Add("H3", "");
+			$this->Add("H4", "");
+			$this->Add("H5", "");
+			$this->Add("H6", "");
+			$this->Add("HEAD", "");
+			$this->Add("HR", "");
+			$this->Add("HTML", "");
+			$this->Add("IMG", "");
+			$this->Add("INPUT", "");
+			$this->Add("ISINDEX", "");
+			$this->Add("I", "");
+			$this->Add("KBD", "");
+			$this->Add("LINK", "");
+			$this->Add("LI", "");
+			$this->Add("MAP", "");
+			$this->Add("MENU", "");
+			$this->Add("META", "");
+			$this->Add("OL", "");
+			$this->Add("OPTION", "");
+			$this->Add("PARAM", "");
+			$this->Add("PRE", "");
+			$this->Add("P", "");
+			$this->Add("SAMP", "");
+			$this->Add("SCRIPT", "");
+			$this->Add("SELECT", "");
+			$this->Add("SMALL", "");
+			$this->Add("STRIKE", "");
+			$this->Add("STRONG", "");
+			$this->Add("STYLE", "");
+			$this->Add("SUB", "");
+			$this->Add("SUP", "");
+			$this->Add("TABLE", "");
+			$this->Add("TD", "");
+			$this->Add("TEXTAREA", "");
+			$this->Add("TH", "");
+			$this->Add("TITLE", "");
+			$this->Add("TR", "");
+			$this->Add("TT", "");
+			$this->Add("UL", "");
+			$this->Add("U", "");
+			$this->Add("VAR", "");
+		}
+	}
+  
+	function SetHTML($html) {
+		$this->html = ($html != false);
+	}
+  
+	function Add($key, $codestr) {
+		$key = strtolower($key);
+		//    $codestr = strtolower($codestr);
+		if(!isset($this->css[$key])) {
+			$this->css[$key] = array();
+		}
+		$codes = explode(";",$codestr);
+		if(count($codes) > 0) {
+			foreach($codes as $code) {
+				$code = trim($code);
+				@list($codekey, $codevalue) = explode(":",$code);
+				if(strlen($codekey) > 0) {
+					$this->css[$key][trim($codekey)] = trim($codevalue);
+				}
+			}
+		}
+	}
+  
+	function Get($key, $property) {
+		$key = strtolower($key);
+		//    $property = strtolower($property);
+		@list($tag, $subtag) = explode(":",$key);
+		@list($tag, $class) = explode(".",$tag);
+		@list($tag, $id) = explode("#",$tag);
+		$result = "";
+		foreach($this->css as $_tag => $value) {
+			@list($_tag, $_subtag) = explode(":",$_tag);
+			@list($_tag, $_class) = explode(".",$_tag);
+			@list($_tag, $_id) = explode("#",$_tag);
+            $tagmatch = (strcmp($tag, $_tag) == 0) | (strlen($_tag) == 0);
+			$subtagmatch = (strcmp($subtag, $_subtag) == 0) | (strlen($_subtag) == 0);
+			$classmatch = (strcmp($class, $_class) == 0) | (strlen($_class) == 0);
+			$idmatch = (strcmp($id, $_id) == 0);
+            if($tagmatch & $subtagmatch & $classmatch & $idmatch) {
+				$temp = $_tag;
+				if((strlen($temp) > 0) & (strlen($_class) > 0)) {
+					$temp .= ".".$_class;
+				}
+				elseif(strlen($temp) == 0) {
+					$temp = ".".$_class;
+				}
+				if((strlen($temp) > 0) & (strlen($_subtag) > 0)) {
+					$temp .= ":".$_subtag;
+				}
+				elseif(strlen($temp) == 0) {
+					$temp = ":".$_subtag;
+				}
+				if(isset($this->css[$temp][$property])) {
+					$result = $this->css[$temp][$property];
+				}
+			}
+		}
+		return $result;
+	}
+  
+	function GetSection($key) {
+		$key = strtolower($key);
+        @list($tag, $subtag) = explode(":",$key);
+		@list($tag, $class) = explode(".",$tag);
+		@list($tag, $id) = explode("#",$tag);
+		$result = array();
+		foreach($this->css as $_tag => $value) {
+			@list($_tag, $_subtag) = explode(":",$_tag);
+			@list($_tag, $_class) = explode(".",$_tag);
+			@list($_tag, $_id) = explode("#",$_tag);
+			$tagmatch = (strcmp($tag, $_tag) == 0) | (strlen($_tag) == 0);
+			$subtagmatch = (strcmp($subtag, $_subtag) == 0) | (strlen($_subtag) == 0);
+			$classmatch = (strcmp($class, $_class) == 0) | (strlen($_class) == 0);
+			$idmatch = (strcmp($id, $_id) == 0);
+			if($tagmatch & $subtagmatch & $classmatch & $idmatch) {
+				$temp = $_tag;
+				if((strlen($temp) > 0) & (strlen($_class) > 0)) {
+					$temp .= ".".$_class;
+				}
+				elseif(strlen($temp) == 0) {
+					$temp = ".".$_class;
+				}
+				if((strlen($temp) > 0) & (strlen($_subtag) > 0)) {
+					$temp .= ":".$_subtag;
+				}
+				elseif(strlen($temp) == 0) {
+					$temp = ":".$_subtag;
+				}	
+				foreach($this->css[$temp] as $property => $value) {
+					$result[$property] = $value;
+				}
+			}
+		}
+		return $result;
+	}
+  
+	function ParseStr($str) {
+		$this->Clear();
+		// Remove comments
+		$str = preg_replace("/\/\*(.*)?\*\//Usi", "", $str);
+		// Parse this damn csscode
+		$parts = explode("}",$str);
+		if(count($parts) > 0) {
+			foreach($parts as $part) {
+				@list($keystr,$codestr) = explode("{",$part);
+				$keys = explode(",",trim($keystr));
+				if(count($keys) > 0) {
+					foreach($keys as $key) {
+						if(strlen($key) > 0) {
+							$key = str_replace("\n", "", $key);
+							$key = str_replace("\\", "", $key);
+							$this->Add($key, trim($codestr));
+						}
+					}
+				}
+			}
+		}
+		//
+		return (count($this->css) > 0);
+	}
+  
+	function Parse($filename) {
+		$this->Clear();
+		if(file_exists($filename)) {
+			return $this->ParseStr(file_get_contents($filename));
+		}
+		else {
+			return false;
+		}
+	}
+	
+	function GetCSS() {
+		$result = "";
+		foreach($this->css as $key => $values) {
+			$result .= $key." {\n";
+			foreach($values as $key => $value) {
+				$result .= "  $key: $value;\n";
+			}
+			$result .= "}\n\n";
+		}
+		return $result;
+	}
+
+	function GetXML() {
+		// Construction of "fckstyles.xml" for FCKeditor
+		$styles = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"."\n";
+		$styles .= '<Styles>'."\n";
+		foreach ($this->css as $key => $value) {
+			// skip all CSS that are a combination of CSS
+			// skip CSS that are binded on an EVENT
+			if (strpos($key, " ") === false && strpos($key, ":") === false) {
+				$pieces = explode(".", $key, 2);
+				if (strcmp($pieces[0], "") != 0) {
+					continue;
+				} else {
+					$style_elem = "span";
+				}
+				if (strcmp($pieces[1], "") != 0) {
+					$style_class_name = $pieces[1];
+				} else {
+					$style_class_name = $pieces[0];
+				}
+				$styles .= '<Style name="'.$style_class_name.'" element="'.$style_elem.'"';
+				if (strcmp($style_class_name, $style_elem) != 0) {
+					$styles .= '>'."\n".'<Attribute name="class" value="'.$style_class_name.'" />'."\n".'</Style>'."\n";
+				} else {
+					$styles .= '/>'."\n";
+				}
+			}
+		}
+		$styles .= '</Styles>'."\n";
+		return trim($styles);
+	}
+}
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/fckeditor/include.php
===================================================================
--- branches/2.8.x/wb/modules/fckeditor/include.php	(revision 1419)
+++ branches/2.8.x/wb/modules/fckeditor/include.php	(revision 1420)
@@ -1,113 +1,115 @@
-<?php
-/**
- *
- * @category        modules
- * @package         wysiwyg
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-function reverse_htmlentities($mixed) {
-	$mixed = str_replace(array('&gt;','&lt;','&quot;','&amp;'), array('>','<','"','&'), $mixed);
-	return $mixed;
-}
-
-function get_template_name() {
-	global $database;
-	// returns the template name of the current displayed page
-
-	// Loading config.php is not needed here, it is loaded before. It breaks the module when the editor is called form another dir as WB_PATH/modules/mymodule
-	// require_once('../../config.php');
-
-	// work out default editor.css file for CKeditor
-	if(file_exists(WB_PATH .'/templates/' .DEFAULT_TEMPLATE .'/editor.css')) {
-		$fck_template_dir = DEFAULT_TEMPLATE;
-	} else {
-		$fck_template_dir = "none";
-	}
-
-	// check if a editor.css file exists in the specified template directory of current page
-	if (isset($_GET["page_id"]) && (int) $_GET["page_id"] > 0) {
-		$pageid = (int) $_GET["page_id"];
-
-		// obtain template folder of current page from the database
-		$query_page = "SELECT template FROM " .TABLE_PREFIX ."pages WHERE page_id =$pageid";
-		$pagetpl = $database->get_one($query_page);   // if empty, default template is used
-
-		// check if a specific template is defined for current page
-		if(isset($pagetpl) && $pagetpl != '') {
-			// check if a specify editor.css file is contained in that folder
-			if(file_exists(WB_PATH.'/templates/'.$pagetpl.'/editor.css')) {
-				$fck_template_dir = $pagetpl;
-			}
-		}
-	}
-	return $fck_template_dir;
-}
-
-function show_wysiwyg_editor($name, $id, $content, $width, $height) {
-	// create new CKeditor instance
-	require_once(WB_PATH.'/modules/fckeditor/fckeditor/fckeditor.php');
-	$oFCKeditor = new FCKeditor($name);
-
-	// set defaults (Note: custom settings defined in: "/my_config/my_fckconfig.js" instead of "/editor/fckconfig.js")
-	$oFCKeditor->BasePath = WB_URL.'/modules/fckeditor/fckeditor/';
-	$oFCKeditor->Config['CustomConfigurationsPath'] = WB_URL .'/modules/fckeditor/wb_config/wb_fckconfig.js';
-	$oFCKeditor->ToolbarSet = 'WBToolbar';        // toolbar defined in my_fckconfig.js
-
-	// obtain template name of current page (if empty, no editor.css files exists)
-	$template_name = get_template_name();
-
-	// work out default CSS file to be used for FCK textarea
-	if($template_name == "none") {
-		// no editor.css file exists in default template folder, or template folder of current page
-		$css_file = WB_URL .'/modules/fckeditor/wb_config/wb_fckeditorarea.css';
-	} else {
-		// editor.css file exists in default template folder or template folder of current page
-		$css_file = WB_URL .'/templates/' .$template_name .'/editor.css';
-	}
-	// set CSS file depending on $css_file
-	$oFCKeditor->Config['EditorAreaCSS'] = $css_file;
-
-	// work out settings for the FCK "Style" toolbar
-	if ($template_name == "none") {
-		// no custom editor.css exists, use default XML definitions
-		$oFCKeditor->Config['StylesXmlPath'] = WB_URL.'/modules/fckeditor/wb_config/wb_fckstyles.xml';
-	} else {
-		// file editor.css exists in template folder, parse it and create XML definitions
-		$oFCKeditor->Config['StylesXmlPath'] = WB_URL.'/modules/fckeditor/css_to_xml.php?template_name=' .$template_name;
-	}
-
-	// custom templates can be defined via /wb_config/wb_fcktemplates.xml
-	if(file_exists(WB_PATH .'/modules/fckeditor/wb_config/wb_fcktemplates.xml')) {
-		$oFCKeditor->Config['TemplatesXmlPath'] = WB_URL.'/modules/fckeditor/wb_config/wb_fcktemplates.xml';
-	}
-
-  // set required file connectors (overwrite settings which may be made in fckconfig.js or my_fckconfig.js)
-	$connectorPath = $oFCKeditor->BasePath.'editor/filemanager/connectors/php/connector.php';
-  $oFCKeditor->Config['LinkBrowserURL'] = $oFCKeditor->BasePath.'editor/filemanager/browser/default/browser.html?Connector='
-		.$connectorPath;
-  $oFCKeditor->Config['ImageBrowserURL'] = $oFCKeditor->BasePath.'editor/filemanager/browser/default/browser.html?Connector='
-		.$connectorPath;
-  $oFCKeditor->Config['FlashBrowserURL'] = $oFCKeditor->BasePath.'editor/filemanager/browser/default/browser.html?Connector='
-		.$connectorPath;
-
-  if(defined('EDITOR_WIDTH'))
-  {
-    $width = ( ($width > EDITOR_WIDTH ) OR (EDITOR_WIDTH <= 0) ) ? $width : EDITOR_WIDTH;
-  }
-
-	$oFCKeditor->Value = reverse_htmlentities($content);
-    $oFCKeditor->Width  = $width;
-	$oFCKeditor->Height = $height;
-	$oFCKeditor->Create();
-}
+<?php
+/**
+ *
+ * @category        modules
+ * @package         wysiwyg
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+function reverse_htmlentities($mixed) {
+	$mixed = str_replace(array('&gt;','&lt;','&quot;','&amp;'), array('>','<','"','&'), $mixed);
+	return $mixed;
+}
+
+function get_template_name() {
+	global $database;
+	// returns the template name of the current displayed page
+
+	// Loading config.php is not needed here, it is loaded before. It breaks the module when the editor is called form another dir as WB_PATH/modules/mymodule
+	// require_once('../../config.php');
+
+	// work out default editor.css file for CKeditor
+	if(file_exists(WB_PATH .'/templates/' .DEFAULT_TEMPLATE .'/editor.css')) {
+		$fck_template_dir = DEFAULT_TEMPLATE;
+	} else {
+		$fck_template_dir = "none";
+	}
+
+	// check if a editor.css file exists in the specified template directory of current page
+	if (isset($_GET["page_id"]) && (int) $_GET["page_id"] > 0) {
+		$pageid = (int) $_GET["page_id"];
+
+		// obtain template folder of current page from the database
+		$query_page = "SELECT template FROM " .TABLE_PREFIX ."pages WHERE page_id =$pageid";
+		$pagetpl = $database->get_one($query_page);   // if empty, default template is used
+
+		// check if a specific template is defined for current page
+		if(isset($pagetpl) && $pagetpl != '') {
+			// check if a specify editor.css file is contained in that folder
+			if(file_exists(WB_PATH.'/templates/'.$pagetpl.'/editor.css')) {
+				$fck_template_dir = $pagetpl;
+			}
+		}
+	}
+	return $fck_template_dir;
+}
+
+function show_wysiwyg_editor($name, $id, $content, $width, $height) {
+	// create new CKeditor instance
+	require_once(WB_PATH.'/modules/fckeditor/fckeditor/fckeditor.php');
+	$oFCKeditor = new FCKeditor($name);
+
+	// set defaults (Note: custom settings defined in: "/my_config/my_fckconfig.js" instead of "/editor/fckconfig.js")
+	$oFCKeditor->BasePath = WB_URL.'/modules/fckeditor/fckeditor/';
+	$oFCKeditor->Config['CustomConfigurationsPath'] = WB_URL .'/modules/fckeditor/wb_config/wb_fckconfig.js';
+	$oFCKeditor->ToolbarSet = 'WBToolbar';        // toolbar defined in my_fckconfig.js
+
+	// obtain template name of current page (if empty, no editor.css files exists)
+	$template_name = get_template_name();
+
+	// work out default CSS file to be used for FCK textarea
+	if($template_name == "none") {
+		// no editor.css file exists in default template folder, or template folder of current page
+		$css_file = WB_URL .'/modules/fckeditor/wb_config/wb_fckeditorarea.css';
+	} else {
+		// editor.css file exists in default template folder or template folder of current page
+		$css_file = WB_URL .'/templates/' .$template_name .'/editor.css';
+	}
+	// set CSS file depending on $css_file
+	$oFCKeditor->Config['EditorAreaCSS'] = $css_file;
+
+	// work out settings for the FCK "Style" toolbar
+	if ($template_name == "none") {
+		// no custom editor.css exists, use default XML definitions
+		$oFCKeditor->Config['StylesXmlPath'] = WB_URL.'/modules/fckeditor/wb_config/wb_fckstyles.xml';
+	} else {
+		// file editor.css exists in template folder, parse it and create XML definitions
+		$oFCKeditor->Config['StylesXmlPath'] = WB_URL.'/modules/fckeditor/css_to_xml.php?template_name=' .$template_name;
+	}
+
+	// custom templates can be defined via /wb_config/wb_fcktemplates.xml
+	if(file_exists(WB_PATH .'/modules/fckeditor/wb_config/wb_fcktemplates.xml')) {
+		$oFCKeditor->Config['TemplatesXmlPath'] = WB_URL.'/modules/fckeditor/wb_config/wb_fcktemplates.xml';
+	}
+
+  // set required file connectors (overwrite settings which may be made in fckconfig.js or my_fckconfig.js)
+	$connectorPath = $oFCKeditor->BasePath.'editor/filemanager/connectors/php/connector.php';
+  $oFCKeditor->Config['LinkBrowserURL'] = $oFCKeditor->BasePath.'editor/filemanager/browser/default/browser.html?Connector='
+		.$connectorPath;
+  $oFCKeditor->Config['ImageBrowserURL'] = $oFCKeditor->BasePath.'editor/filemanager/browser/default/browser.html?Connector='
+		.$connectorPath;
+  $oFCKeditor->Config['FlashBrowserURL'] = $oFCKeditor->BasePath.'editor/filemanager/browser/default/browser.html?Connector='
+		.$connectorPath;
+
+  if(defined('EDITOR_WIDTH'))
+  {
+    $width = ( ($width > EDITOR_WIDTH ) OR (EDITOR_WIDTH <= 0) ) ? $width : EDITOR_WIDTH;
+  }
+
+	$oFCKeditor->Value = reverse_htmlentities($content);
+    $oFCKeditor->Width  = $width;
+	$oFCKeditor->Height = $height;
+	$oFCKeditor->Create();
+}
Index: branches/2.8.x/wb/modules/droplets/droplets.php
===================================================================
--- branches/2.8.x/wb/modules/droplets/droplets.php	(revision 1419)
+++ branches/2.8.x/wb/modules/droplets/droplets.php	(revision 1420)
@@ -1,113 +1,116 @@
-<?php
-/**
- *
- * @category        module
- * @package         droplets
- * @author          Ruud Eisinga (Ruud) John (PCWacht)
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- *	droplets are small codeblocks that are called from anywhere in the template.
- * 	To call a droplet just use [[dropletname]]. optional parameters for a droplet can be used like [[dropletname?parameter=value&parameter2=value]]\
- *
- *  1.0.2, bugfix, Reused the evalDroplet function so the extracted parameters will be only available within the scope of the eval and cleared when ready.
- *  1.0.3, optimize, reduce memory consumption, increase speed, remove CSS, enable nested droplets
- *
- */
-
-	function do_eval($_x_codedata, $_x_varlist, &$wb_page_data)
-	{
-		extract($_x_varlist, EXTR_SKIP);
-		return(eval($_x_codedata));
-	}
-
-	function processDroplets( &$wb_page_data ) {
-// collect all droplets from document
-		$droplet_tags = array();
-		$droplet_replacements = array();
-		if( preg_match_all( '/\[\[(.*?)\]\]/', $wb_page_data, $found_droplets ) )
-		{
-			foreach( $found_droplets[1] as $droplet )
-			{
-				if(array_key_exists( '[['.$droplet.']]', $droplet_tags) == false)
-				{
-// go in if same droplet with same arguments is not processed already
-					$varlist = array();
-// split each droplet command into droplet_name and request_string
-					$tmp = preg_split('/\?/', $droplet, 2);
-					$droplet_name = $tmp[0];
-					$request_string = (isset($tmp[1]) ? $tmp[1] : '');
-					if( $request_string != '' )
-					{
-// make sure we can parse the arguments correctly
-						$request_string = html_entity_decode($request_string, ENT_COMPAT,DEFAULT_CHARSET);
-// create array of arguments from query_string
-						$argv = preg_split( '/&(?!amp;)/', $request_string );
-						foreach ($argv as $argument)
-						{
-// split argument in pair of varname, value
-							list( $variable, $value ) = explode('=', $argument,2);
-							if( !empty($value) )
-							{
-// re-encode the value and push the var into varlist
-								$varlist[$variable] = htmlentities($value, ENT_COMPAT,DEFAULT_CHARSET);
-							}
-						}
-					}
-					else
-					{
-// no arguments given, so
-						$droplet_name = $droplet;
-					}
-// request the droplet code from database
-					$sql = 'SELECT `code` FROM `'.TABLE_PREFIX.'mod_droplets` WHERE `name` LIKE "'.$droplet_name.'" AND `active` = 1';
-					$codedata = $GLOBALS['database']->get_one($sql);
-					if (!is_null($codedata))
-					{
-						$newvalue = do_eval($codedata, $varlist, $wb_page_data);
-// check returnvalue (must be a string of 1 char at least or (bool)true
-						if ($newvalue == '' && $newvalue !== true)
-						{
-							if(DEBUG === true)
-							{
-								$newvalue = '<span class="mod_droplets_err">Error in: '.$droplet.', no valid returnvalue.</span>';
-							}
-							else
-							{
-								$newvalue = true;
-							}
-						}
-						if ($newvalue === true) { $newvalue = ""; }
-// remove any defined CSS section from code. For valid XHTML a CSS-section is allowed inside <head>...</head> only!
-						$newvalue = preg_replace('/<style.*>.*<\/style>/siU', '', $newvalue);
-// push droplet-tag and it's replacement into Search/Replace array after executing only
-						$droplet_tags[]         = '[['.$droplet.']]';
-						$droplet_replacements[] = $newvalue;
-					}
-				}
-			}	// End foreach( $found_droplets[1] as $droplet )
-// replace each Droplet-Tag with coresponding $newvalue
-			$wb_page_data = str_replace($droplet_tags, $droplet_replacements, $wb_page_data);
-		}
-// returns TRUE if droplets found in content, FALSE if not
-		return( count($droplet_tags)!=0 );
-	}
-
-	function evalDroplets( &$wb_page_data, $max_loops = 3 ) {
-		$max_loops = ((int)$max_loops = 0 ? 3 : (int)$max_loops);
-		while( (processDroplets($wb_page_data) == true) && ($max_loops > 0))
-		{ 
-			$max_loops--;
-		}
-		return $wb_page_data;
-	}
-
+<?php
+/**
+ *
+ * @category        module
+ * @package         droplets
+ * @author          Ruud Eisinga (Ruud) John (PCWacht)
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ *	droplets are small codeblocks that are called from anywhere in the template.
+ * 	To call a droplet just use [[dropletname]]. optional parameters for a droplet can be used like [[dropletname?parameter=value&parameter2=value]]\
+ *
+ *  1.0.2, bugfix, Reused the evalDroplet function so the extracted parameters will be only available within the scope of the eval and cleared when ready.
+ *  1.0.3, optimize, reduce memory consumption, increase speed, remove CSS, enable nested droplets
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+	function do_eval($_x_codedata, $_x_varlist, &$wb_page_data)
+	{
+		extract($_x_varlist, EXTR_SKIP);
+		return(eval($_x_codedata));
+	}
+
+	function processDroplets( &$wb_page_data ) {
+// collect all droplets from document
+		$droplet_tags = array();
+		$droplet_replacements = array();
+		if( preg_match_all( '/\[\[(.*?)\]\]/', $wb_page_data, $found_droplets ) )
+		{
+			foreach( $found_droplets[1] as $droplet )
+			{
+				if(array_key_exists( '[['.$droplet.']]', $droplet_tags) == false)
+				{
+// go in if same droplet with same arguments is not processed already
+					$varlist = array();
+// split each droplet command into droplet_name and request_string
+					$tmp = preg_split('/\?/', $droplet, 2);
+					$droplet_name = $tmp[0];
+					$request_string = (isset($tmp[1]) ? $tmp[1] : '');
+					if( $request_string != '' )
+					{
+// make sure we can parse the arguments correctly
+						$request_string = html_entity_decode($request_string, ENT_COMPAT,DEFAULT_CHARSET);
+// create array of arguments from query_string
+						$argv = preg_split( '/&(?!amp;)/', $request_string );
+						foreach ($argv as $argument)
+						{
+// split argument in pair of varname, value
+							list( $variable, $value ) = explode('=', $argument,2);
+							if( !empty($value) )
+							{
+// re-encode the value and push the var into varlist
+								$varlist[$variable] = htmlentities($value, ENT_COMPAT,DEFAULT_CHARSET);
+							}
+						}
+					}
+					else
+					{
+// no arguments given, so
+						$droplet_name = $droplet;
+					}
+// request the droplet code from database
+					$sql = 'SELECT `code` FROM `'.TABLE_PREFIX.'mod_droplets` WHERE `name` LIKE "'.$droplet_name.'" AND `active` = 1';
+					$codedata = $GLOBALS['database']->get_one($sql);
+					if (!is_null($codedata))
+					{
+						$newvalue = do_eval($codedata, $varlist, $wb_page_data);
+// check returnvalue (must be a string of 1 char at least or (bool)true
+						if ($newvalue == '' && $newvalue !== true)
+						{
+							if(DEBUG === true)
+							{
+								$newvalue = '<span class="mod_droplets_err">Error in: '.$droplet.', no valid returnvalue.</span>';
+							}
+							else
+							{
+								$newvalue = true;
+							}
+						}
+						if ($newvalue === true) { $newvalue = ""; }
+// remove any defined CSS section from code. For valid XHTML a CSS-section is allowed inside <head>...</head> only!
+						$newvalue = preg_replace('/<style.*>.*<\/style>/siU', '', $newvalue);
+// push droplet-tag and it's replacement into Search/Replace array after executing only
+						$droplet_tags[]         = '[['.$droplet.']]';
+						$droplet_replacements[] = $newvalue;
+					}
+				}
+			}	// End foreach( $found_droplets[1] as $droplet )
+// replace each Droplet-Tag with coresponding $newvalue
+			$wb_page_data = str_replace($droplet_tags, $droplet_replacements, $wb_page_data);
+		}
+// returns TRUE if droplets found in content, FALSE if not
+		return( count($droplet_tags)!=0 );
+	}
+
+	function evalDroplets( &$wb_page_data, $max_loops = 3 ) {
+		$max_loops = ((int)$max_loops = 0 ? 3 : (int)$max_loops);
+		while( (processDroplets($wb_page_data) == true) && ($max_loops > 0))
+		{ 
+			$max_loops--;
+		}
+		return $wb_page_data;
+	}
+
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/droplets/install.php
===================================================================
--- branches/2.8.x/wb/modules/droplets/install.php	(revision 1419)
+++ branches/2.8.x/wb/modules/droplets/install.php	(revision 1420)
@@ -1,96 +1,95 @@
-<?php
-/**
- *
- * @category        module
- * @package         droplet
- * @author          Ruud Eisinga (Ruud) John (PCWacht)
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// prevent this file from being accessed directly
-if(!defined('WB_PATH')) die(header('Location: ../../index.php'));
-
-global $admin;
-
-$table = TABLE_PREFIX .'mod_droplets';
-$database->query("DROP TABLE IF EXISTS `$table`");
-
-$database->query("CREATE TABLE `$table` (
-	`id` INT NOT NULL auto_increment,
-	`name` VARCHAR(32) NOT NULL,
-	`code` LONGTEXT NOT NULL ,
-	`description` TEXT NOT NULL,
-	`modified_when` INT NOT NULL default '0',
-	`modified_by` INT NOT NULL default '0',
-	`active` INT NOT NULL default '0',
-	`admin_edit` INT NOT NULL default '0',
-	`admin_view` INT NOT NULL default '0',
-	`show_wysiwyg` INT NOT NULL default '0',
-	`comments` TEXT NOT NULL,
-	PRIMARY KEY ( `id` )
-	)"
-);
-
-//add all droplets from the droplet subdirectory
-$folder=opendir(WB_PATH.'/modules/droplets/example/.'); 
-$names = array();
-while ($file = readdir($folder)) {
-	$ext=strtolower(substr($file,-4));
-	if ($ext==".php"){
-		if ($file<>"index.php" ) {
-			$names[count($names)] = $file; 
-		}
-	}
-}
-closedir($folder);
-
-foreach ($names as $dropfile) {
-	$droplet = addslashes(getDropletCodeFromFile($dropfile));
-	if ($droplet != "") {
-		$description = "Example Droplet";
-		$comments = "Example Droplet";
-		$cArray = explode("\n",$droplet);
-		if (substr($cArray[0],0,3) == "//:") {
-			$description = trim(substr($cArray[0],3));
-			array_shift ( $cArray );
-		}
-		if (substr($cArray[0],0,3) == "//:") {
-			$comments = trim(substr($cArray[0],3));
-			array_shift ( $cArray );
-		}
-		$droplet = implode ( "\n", $cArray );
-		$name = substr($dropfile,0,-4);
-		$modified_when = time();
-		$modified_by = method_exists($admin, 'get_user_id') ? $admin->get_user_id() : 1;
-		$database->query("INSERT INTO `$table`  
-			(name, code, description, comments, active, modified_when, modified_by) 
-			VALUES 
-			('$name', '$droplet', '$description', '$comments', '1', '$modified_when', '$modified_by')");
-		
-		// do not output anything if this script is called during fresh installation
-		if (method_exists($admin, 'get_user_id')) echo "Droplet import: $name<br/>";
-	}  
-}
-
-function getDropletCodeFromFile ( $dropletfile ) {
-	$data = "";
-	$filename = WB_PATH."/modules/droplets/example/".$dropletfile;
-	if (file_exists($filename)) {
-		$filehandle = fopen ($filename, "r");
-		$data = fread ($filehandle, filesize ($filename));
-		fclose($filehandle);
-		// unlink($filename); doesnt work in unix
-	}	
-	return $data;
-}
+<?php
+/**
+ *
+ * @category        module
+ * @package         droplet
+ * @author          Ruud Eisinga (Ruud) John (PCWacht)
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+global $admin;
+
+$table = TABLE_PREFIX .'mod_droplets';
+$database->query("DROP TABLE IF EXISTS `$table`");
+
+$database->query("CREATE TABLE `$table` (
+	`id` INT NOT NULL auto_increment,
+	`name` VARCHAR(32) NOT NULL,
+	`code` LONGTEXT NOT NULL ,
+	`description` TEXT NOT NULL,
+	`modified_when` INT NOT NULL default '0',
+	`modified_by` INT NOT NULL default '0',
+	`active` INT NOT NULL default '0',
+	`admin_edit` INT NOT NULL default '0',
+	`admin_view` INT NOT NULL default '0',
+	`show_wysiwyg` INT NOT NULL default '0',
+	`comments` TEXT NOT NULL,
+	PRIMARY KEY ( `id` )
+	)"
+);
+
+//add all droplets from the droplet subdirectory
+$folder=opendir(WB_PATH.'/modules/droplets/example/.'); 
+$names = array();
+while ($file = readdir($folder)) {
+	$ext=strtolower(substr($file,-4));
+	if ($ext==".php"){
+		if ($file<>"index.php" ) {
+			$names[count($names)] = $file; 
+		}
+	}
+}
+closedir($folder);
+
+foreach ($names as $dropfile) {
+	$droplet = addslashes(getDropletCodeFromFile($dropfile));
+	if ($droplet != "") {
+		$description = "Example Droplet";
+		$comments = "Example Droplet";
+		$cArray = explode("\n",$droplet);
+		if (substr($cArray[0],0,3) == "//:") {
+			$description = trim(substr($cArray[0],3));
+			array_shift ( $cArray );
+		}
+		if (substr($cArray[0],0,3) == "//:") {
+			$comments = trim(substr($cArray[0],3));
+			array_shift ( $cArray );
+		}
+		$droplet = implode ( "\n", $cArray );
+		$name = substr($dropfile,0,-4);
+		$modified_when = time();
+		$modified_by = method_exists($admin, 'get_user_id') ? $admin->get_user_id() : 1;
+		$database->query("INSERT INTO `$table`  
+			(name, code, description, comments, active, modified_when, modified_by) 
+			VALUES 
+			('$name', '$droplet', '$description', '$comments', '1', '$modified_when', '$modified_by')");
+		
+		// do not output anything if this script is called during fresh installation
+		if (method_exists($admin, 'get_user_id')) echo "Droplet import: $name<br/>";
+	}  
+}
+
+function getDropletCodeFromFile ( $dropletfile ) {
+	$data = "";
+	$filename = WB_PATH."/modules/droplets/example/".$dropletfile;
+	if (file_exists($filename)) {
+		$filehandle = fopen ($filename, "r");
+		$data = fread ($filehandle, filesize ($filename));
+		fclose($filehandle);
+		// unlink($filename); doesnt work in unix
+	}	
+	return $data;
+}
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/droplets/tool.php
===================================================================
--- branches/2.8.x/wb/modules/droplets/tool.php	(revision 1419)
+++ branches/2.8.x/wb/modules/droplets/tool.php	(revision 1420)
@@ -1,156 +1,156 @@
-<?php
-/**
- *
- * @category        module
- * @package         droplet
- * @author          Ruud Eisinga (Ruud) John (PCWacht)
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// Direct access prevention
-defined('WB_PATH') OR die(header('Location: ../index.php'));
-
-// Load Language file
-if(LANGUAGE_LOADED) {
-	if(!file_exists(WB_PATH.'/modules/droplets/languages/'.LANGUAGE.'.php')) {
-		require_once(WB_PATH.'/modules/droplets/languages/EN.php');
-	} else {
-		require_once(WB_PATH.'/modules/droplets/languages/'.LANGUAGE.'.php');
-	}
-}
-
-// check if backend.css file needs to be included into the <body></body>
-if(!method_exists($admin, 'register_backend_modfiles') && file_exists(WB_PATH .'/modules/droplets/backend.css')) {
-	echo '<style type="text/css">';
-	include(WB_PATH .'/modules/droplets/backend.css');
-	echo "\n</style>\n";
-}
-
-// Get userid for showing admin only droplets or not
-$loggedin_user = $admin->get_user_id();
-	
-// And... action
-$admintool_url = ADMIN_URL .'/admintools/index.php';
-
-//removes empty entries from the table so they will not be displayed
-$database->query("DELETE FROM ".TABLE_PREFIX."mod_droplets WHERE name=''");
-?>
-
-<br />
-<table cellpadding="0" cellspacing="0" border="0" width="100%">
-<tr>
-	<td valign="bottom" width="50%">
-		<button class="add" type="button" name="add_droplet" onclick="javascript: window.location = '<?php echo WB_URL; ?>/modules/droplets/add_droplet.php';"><?php echo $TEXT['ADD'].' '.$DR_TEXT['DROPLETS']; ?></button>	
-	</td>
-	<!-- commentet out the droplets logo for a more similar backend design with other admin tools
-	<td align="center"><img src="<?php /*echo WB_URL;*/ ?>/modules/droplets/img/droplets_logo.png" border="1" alt=""/></td>
-	-->
-	<td valign="top" width="50%" align="right">
-		<a href="#" onclick="javascript: window.open('<?php echo WB_URL; ?>/modules/droplets/readme/<?php echo $DR_TEXT['README']; ?>','helpwindow','width=700,height=550,directories=no,location=no,menubar=no,scrollbars=yes,status=no,toolbar=no,resizable=yes');"><?php echo $DR_TEXT['HELP']; ?></a>
-		<br /><br />
-		<a href="#" onclick="javascript: window.location = '<?php echo WB_URL; ?>/modules/droplets/backup_droplets.php?id=<?php echo $admin->getIDKEY(999) . '\';">' .$DR_TEXT['BACKUP']; ?></a>
-	</td>
-</tr>
-</table>
-<br />
-
-<h2><?php echo $TEXT['MODIFY'].'/'.$TEXT['DELETE'].' '.$DR_TEXT['DROPLETS']; ?></h2>
-<?php
-if ($loggedin_user == '1') {
-	$query_droplets = $database->query("SELECT * FROM ".TABLE_PREFIX."mod_droplets ORDER BY modified_when DESC");
-} else { 
-	$query_droplets = $database->query("SELECT * FROM ".TABLE_PREFIX."mod_droplets WHERE admin_view <> '1' ORDER BY modified_when DESC");
-}
-$num_droplets = $query_droplets->numRows();
-if($num_droplets > 0) {
-	?>
-	<table class="row_a" border="0" cellspacing="0" cellpadding="3" width="100%">
-	<thead>
-		<tr>
-			<td width="3%"></td>
-			<td width="21%"><?php echo $TEXT['NAME']; ?></td>
-			<td width="68%"><?php echo $TEXT['DESCRIPTION']; ?></td>
-			<td width="4%"><?php echo $TEXT['ACTIVE']; ?></td>
-			<td width="3%"></td>
-		</tr>
-	</thead>
-	<?php
-	$row = 'a';
-	while($droplet = $query_droplets->fetchRow()) {
-		$get_modified_user = $database->query("SELECT display_name,username, user_id FROM ".TABLE_PREFIX."users WHERE user_id = '".$droplet['modified_by']."' LIMIT 1");
-		if($get_modified_user->numRows() > 0) {
-			$fetch_modified_user = $get_modified_user->fetchRow();
-			$modified_user = $fetch_modified_user['username'];
-			$modified_userid = $fetch_modified_user['user_id'];
-		} else {
-			$modified_user = $TEXT['UNKNOWN'];
-			$modified_userid = 0;
-		}
-		$comments = str_replace(array("\r\n", "\n", "\r"), '<br />', $droplet['comments']);
-		if (!strpos($comments,"[[")) $comments = "Use: [[".$droplet['name']."]]<br />".$comments;
-		$comments = str_replace(array("[[", "]]"), array('<b>[[',']]</b>'), $comments);
-		$valid_code = check_syntax($droplet['code']);
-		if (!$valid_code === true) $comments = '<font color=\'red\'><strong>'.$DR_TEXT['INVALIDCODE'].'</strong></font><br /><br />'.$comments;
-		$unique_droplet = check_unique ($droplet['name']);
-		if ($unique_droplet === false) $comments = '<font color=\'red\'><strong>'.$DR_TEXT['NOTUNIQUE'].'</strong></font><br /><br />'.$comments;
-		$comments = '<span>'.$comments.'</span>';
-		?>
-		
-		<tr class="row_<?php echo $row; ?>" >
-			<td >
-				<a href="<?php echo WB_URL; ?>/modules/droplets/modify_droplet.php?droplet_id=<?php echo $admin->getIDKEY($droplet['id']); ?>" title="<?php echo $TEXT['MODIFY']; ?>">
-					<img src="<?php echo THEME_URL; ?>/images/modify_16.png" border="0" alt="Modify" /> 
-				</a>
-			</td>
-			<td >
-				<a href="<?php echo WB_URL; ?>/modules/droplets/modify_droplet.php?droplet_id=<?php echo $admin->getIDKEY($droplet['id']); ?>" class="tooltip">
-							<?php if ($valid_code && $unique_droplet) { ?><img src="<?php echo WB_URL; ?>/modules/droplets/img/droplet.png" border="0" alt=""/>
-							<?php } else {  ?><img src="<?php echo WB_URL; ?>/modules/droplets/img/invalid.gif" border="0" title="" alt=""/><?php }  ?>
-					<?php echo $droplet['name']; ?><?php echo $comments; ?>
-				</a>
-			</td>
-			<td >
-				<small><?php echo substr($droplet['description'],0,90); ?></small>
-			</td>
-			<td >
-				<b><?php if($droplet['active'] == 1){ echo '<span style="color: green;">'. $TEXT['YES']. '</span>'; } else { echo '<span style="color: red;">'.$TEXT['NO'].'</span>';  } ?></b>
-			</td>
-			<td >
-				<a href="javascript: confirm_link('<?php echo $TEXT['ARE_YOU_SURE']; ?>', '<?php echo WB_URL; ?>/modules/droplets/delete_droplet.php?droplet_id=<?php echo $admin->getIDKEY($droplet['id']); ?>');" title="<?php echo $TEXT['DELETE']; ?>">
-					<img src="<?php echo THEME_URL; ?>/images/delete_16.png" border="0" alt="X" />
-				</a>
-			</td>
-		</tr>
-		<?php
-		// Alternate row color
-		if($row == 'a') {
-			$row = 'b';
-		} else {
-			$row = 'a';
-		}
-	}
-	?>
-	</table>
-	<?php
-}
-
-function check_syntax($code) {
-    return @eval('return true;' . $code);
-}
-
-function check_unique($name) {
-	global $database;
-	$query_droplets = $database->query("SELECT name FROM ".TABLE_PREFIX."mod_droplets WHERE name = '$name'");
-	return ($query_droplets->numRows() == 1);
-}
+<?php
+/**
+ *
+ * @category        module
+ * @package         droplet
+ * @author          Ruud Eisinga (Ruud) John (PCWacht)
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+// Load Language file
+if(LANGUAGE_LOADED) {
+	if(!file_exists(WB_PATH.'/modules/droplets/languages/'.LANGUAGE.'.php')) {
+		require_once(WB_PATH.'/modules/droplets/languages/EN.php');
+	} else {
+		require_once(WB_PATH.'/modules/droplets/languages/'.LANGUAGE.'.php');
+	}
+}
+
+// check if backend.css file needs to be included into the <body></body>
+if(!method_exists($admin, 'register_backend_modfiles') && file_exists(WB_PATH .'/modules/droplets/backend.css')) {
+	echo '<style type="text/css">';
+	include(WB_PATH .'/modules/droplets/backend.css');
+	echo "\n</style>\n";
+}
+
+// Get userid for showing admin only droplets or not
+$loggedin_user = $admin->get_user_id();
+	
+// And... action
+$admintool_url = ADMIN_URL .'/admintools/index.php';
+
+//removes empty entries from the table so they will not be displayed
+$database->query("DELETE FROM ".TABLE_PREFIX."mod_droplets WHERE name=''");
+?>
+
+<br />
+<table cellpadding="0" cellspacing="0" border="0" width="100%">
+<tr>
+	<td valign="bottom" width="50%">
+		<button class="add" type="button" name="add_droplet" onclick="javascript: window.location = '<?php echo WB_URL; ?>/modules/droplets/add_droplet.php';"><?php echo $TEXT['ADD'].' '.$DR_TEXT['DROPLETS']; ?></button>	
+	</td>
+	<!-- commentet out the droplets logo for a more similar backend design with other admin tools
+	<td align="center"><img src="<?php /*echo WB_URL;*/ ?>/modules/droplets/img/droplets_logo.png" border="1" alt=""/></td>
+	-->
+	<td valign="top" width="50%" align="right">
+		<a href="#" onclick="javascript: window.open('<?php echo WB_URL; ?>/modules/droplets/readme/<?php echo $DR_TEXT['README']; ?>','helpwindow','width=700,height=550,directories=no,location=no,menubar=no,scrollbars=yes,status=no,toolbar=no,resizable=yes');"><?php echo $DR_TEXT['HELP']; ?></a>
+		<br /><br />
+		<a href="#" onclick="javascript: window.location = '<?php echo WB_URL; ?>/modules/droplets/backup_droplets.php?id=<?php echo $admin->getIDKEY(999) . '\';">' .$DR_TEXT['BACKUP']; ?></a>
+	</td>
+</tr>
+</table>
+<br />
+
+<h2><?php echo $TEXT['MODIFY'].'/'.$TEXT['DELETE'].' '.$DR_TEXT['DROPLETS']; ?></h2>
+<?php
+if ($loggedin_user == '1') {
+	$query_droplets = $database->query("SELECT * FROM ".TABLE_PREFIX."mod_droplets ORDER BY modified_when DESC");
+} else { 
+	$query_droplets = $database->query("SELECT * FROM ".TABLE_PREFIX."mod_droplets WHERE admin_view <> '1' ORDER BY modified_when DESC");
+}
+$num_droplets = $query_droplets->numRows();
+if($num_droplets > 0) {
+	?>
+	<table class="row_a" border="0" cellspacing="0" cellpadding="3" width="100%">
+	<thead>
+		<tr>
+			<td width="3%"></td>
+			<td width="21%"><?php echo $TEXT['NAME']; ?></td>
+			<td width="68%"><?php echo $TEXT['DESCRIPTION']; ?></td>
+			<td width="4%"><?php echo $TEXT['ACTIVE']; ?></td>
+			<td width="3%"></td>
+		</tr>
+	</thead>
+	<?php
+	$row = 'a';
+	while($droplet = $query_droplets->fetchRow()) {
+		$get_modified_user = $database->query("SELECT display_name,username, user_id FROM ".TABLE_PREFIX."users WHERE user_id = '".$droplet['modified_by']."' LIMIT 1");
+		if($get_modified_user->numRows() > 0) {
+			$fetch_modified_user = $get_modified_user->fetchRow();
+			$modified_user = $fetch_modified_user['username'];
+			$modified_userid = $fetch_modified_user['user_id'];
+		} else {
+			$modified_user = $TEXT['UNKNOWN'];
+			$modified_userid = 0;
+		}
+		$comments = str_replace(array("\r\n", "\n", "\r"), '<br />', $droplet['comments']);
+		if (!strpos($comments,"[[")) $comments = "Use: [[".$droplet['name']."]]<br />".$comments;
+		$comments = str_replace(array("[[", "]]"), array('<b>[[',']]</b>'), $comments);
+		$valid_code = check_syntax($droplet['code']);
+		if (!$valid_code === true) $comments = '<font color=\'red\'><strong>'.$DR_TEXT['INVALIDCODE'].'</strong></font><br /><br />'.$comments;
+		$unique_droplet = check_unique ($droplet['name']);
+		if ($unique_droplet === false) $comments = '<font color=\'red\'><strong>'.$DR_TEXT['NOTUNIQUE'].'</strong></font><br /><br />'.$comments;
+		$comments = '<span>'.$comments.'</span>';
+		?>
+		
+		<tr class="row_<?php echo $row; ?>" >
+			<td >
+				<a href="<?php echo WB_URL; ?>/modules/droplets/modify_droplet.php?droplet_id=<?php echo $admin->getIDKEY($droplet['id']); ?>" title="<?php echo $TEXT['MODIFY']; ?>">
+					<img src="<?php echo THEME_URL; ?>/images/modify_16.png" border="0" alt="Modify" /> 
+				</a>
+			</td>
+			<td >
+				<a href="<?php echo WB_URL; ?>/modules/droplets/modify_droplet.php?droplet_id=<?php echo $admin->getIDKEY($droplet['id']); ?>" class="tooltip">
+							<?php if ($valid_code && $unique_droplet) { ?><img src="<?php echo WB_URL; ?>/modules/droplets/img/droplet.png" border="0" alt=""/>
+							<?php } else {  ?><img src="<?php echo WB_URL; ?>/modules/droplets/img/invalid.gif" border="0" title="" alt=""/><?php }  ?>
+					<?php echo $droplet['name']; ?><?php echo $comments; ?>
+				</a>
+			</td>
+			<td >
+				<small><?php echo substr($droplet['description'],0,90); ?></small>
+			</td>
+			<td >
+				<b><?php if($droplet['active'] == 1){ echo '<span style="color: green;">'. $TEXT['YES']. '</span>'; } else { echo '<span style="color: red;">'.$TEXT['NO'].'</span>';  } ?></b>
+			</td>
+			<td >
+				<a href="javascript: confirm_link('<?php echo $TEXT['ARE_YOU_SURE']; ?>', '<?php echo WB_URL; ?>/modules/droplets/delete_droplet.php?droplet_id=<?php echo $admin->getIDKEY($droplet['id']); ?>');" title="<?php echo $TEXT['DELETE']; ?>">
+					<img src="<?php echo THEME_URL; ?>/images/delete_16.png" border="0" alt="X" />
+				</a>
+			</td>
+		</tr>
+		<?php
+		// Alternate row color
+		if($row == 'a') {
+			$row = 'b';
+		} else {
+			$row = 'a';
+		}
+	}
+	?>
+	</table>
+	<?php
+}
+
+function check_syntax($code) {
+    return @eval('return true;' . $code);
+}
+
+function check_unique($name) {
+	global $database;
+	$query_droplets = $database->query("SELECT name FROM ".TABLE_PREFIX."mod_droplets WHERE name = '$name'");
+	return ($query_droplets->numRows() == 1);
+}
 ?>
\ No newline at end of file
Index: branches/2.8.x/wb/modules/news/search.php
===================================================================
--- branches/2.8.x/wb/modules/news/search.php	(revision 1419)
+++ branches/2.8.x/wb/modules/news/search.php	(revision 1420)
@@ -1,104 +1,107 @@
-<?php
-/**
- *
- * @category        modules
- * @package         news
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-function news_search($func_vars) {
-	extract($func_vars, EXTR_PREFIX_ALL, 'func');
-
-	// how many lines of excerpt we want to have at most
-	$max_excerpt_num = $func_default_max_excerpt;
-	// do we want excerpt from comments?
-	$excerpt_from_comments = true; // TODO: make this configurable
-	$divider = ".";
-	$result = false;
-
-	// fetch all active news-posts (from active groups) in this section.
-	$t = time();
-	$table_posts = TABLE_PREFIX."mod_news_posts";
-	$table_groups = TABLE_PREFIX."mod_news_groups";
-	$query = $func_database->query("
-		SELECT p.post_id, p.title, p.content_short, p.content_long, p.link, p.posted_when, p.posted_by
-		FROM $table_posts AS p LEFT OUTER JOIN $table_groups AS g ON p.group_id = g.group_id
-		WHERE p.section_id='$func_section_id' AND p.active = '1' AND ( g.active IS NULL OR g.active = '1' )
-		AND (published_when = '0' OR published_when <= $t) AND (published_until = 0 OR published_until >= $t)
-		ORDER BY p.post_id DESC
-	");
-	// now call print_excerpt() for every single post
-	if($query->numRows() > 0) {
-		while($res = $query->fetchRow()) {
-			$text = $res['title'].$divider.$res['content_short'].$divider.$res['content_long'].$divider;
-			// fetch comments and add to $text
-			if($excerpt_from_comments) {
-				$table = TABLE_PREFIX."mod_news_comments";
-				$commentquery = $func_database->query("
-					SELECT title, comment
-					FROM $table
-					WHERE post_id='{$res['post_id']}'
-					ORDER BY commented_when ASC
-				");
-				if($commentquery->numRows() > 0) {
-					while($c_res = $commentquery->fetchRow()) {
-						$text .= $c_res['title'].$divider.$c_res['comment'].$divider;
-					}
-				}
-			}
-			$mod_vars = array(
-				'page_link' => $res['link'], // use direct link to news-item
-				'page_link_target' => "",
-				'page_title' => $func_page_title,
-				'page_description' => $res['title'], // use news-title as description
-				'page_modified_when' => $res['posted_when'],
-				'page_modified_by' => $res['posted_by'],
-				'text' => $text,
-				'max_excerpt_num' => $max_excerpt_num
-			);
-			if(print_excerpt2($mod_vars, $func_vars)) {
-				$result = true;
-			}
-		}
-	}
-	
-	// now fetch group-titles - ignore those without (active) postings
-	$table_groups = TABLE_PREFIX."mod_news_groups";
-	$table_posts = TABLE_PREFIX."mod_news_posts";
-	$query = $func_database->query("
-		SELECT DISTINCT g.title, g.group_id
-		FROM $table_groups AS g INNER JOIN $table_posts AS p ON g.group_id = p.group_id
-		WHERE g.section_id='$func_section_id' AND g.active = '1' AND p.active = '1'
-	");
-	// now call print_excerpt() for every single group, too
-	if($query->numRows() > 0) {
-		while($res = $query->fetchRow()) {
-			$mod_vars = array(
-				'page_link' => $func_page_link,
-				'page_link_target' => "&g=".$res['group_id'],
-				'page_title' => $func_page_title,
-				'page_description' => $func_page_description,
-				'page_modified_when' => $func_page_modified_when,
-				'page_modified_by' => $func_page_modified_by,
-				'text' => $res['title'].$divider,
-				'max_excerpt_num' => $max_excerpt_num
-			);
-			if(print_excerpt2($mod_vars, $func_vars)) {
-				$result = true;
-			}
-		}
-	}
-	return $result;
-}
-
-?>
+<?php
+/**
+ *
+ * @category        modules
+ * @package         news
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+function news_search($func_vars) {
+	extract($func_vars, EXTR_PREFIX_ALL, 'func');
+
+	// how many lines of excerpt we want to have at most
+	$max_excerpt_num = $func_default_max_excerpt;
+	// do we want excerpt from comments?
+	$excerpt_from_comments = true; // TODO: make this configurable
+	$divider = ".";
+	$result = false;
+
+	// fetch all active news-posts (from active groups) in this section.
+	$t = time();
+	$table_posts = TABLE_PREFIX."mod_news_posts";
+	$table_groups = TABLE_PREFIX."mod_news_groups";
+	$query = $func_database->query("
+		SELECT p.post_id, p.title, p.content_short, p.content_long, p.link, p.posted_when, p.posted_by
+		FROM $table_posts AS p LEFT OUTER JOIN $table_groups AS g ON p.group_id = g.group_id
+		WHERE p.section_id='$func_section_id' AND p.active = '1' AND ( g.active IS NULL OR g.active = '1' )
+		AND (published_when = '0' OR published_when <= $t) AND (published_until = 0 OR published_until >= $t)
+		ORDER BY p.post_id DESC
+	");
+	// now call print_excerpt() for every single post
+	if($query->numRows() > 0) {
+		while($res = $query->fetchRow()) {
+			$text = $res['title'].$divider.$res['content_short'].$divider.$res['content_long'].$divider;
+			// fetch comments and add to $text
+			if($excerpt_from_comments) {
+				$table = TABLE_PREFIX."mod_news_comments";
+				$commentquery = $func_database->query("
+					SELECT title, comment
+					FROM $table
+					WHERE post_id='{$res['post_id']}'
+					ORDER BY commented_when ASC
+				");
+				if($commentquery->numRows() > 0) {
+					while($c_res = $commentquery->fetchRow()) {
+						$text .= $c_res['title'].$divider.$c_res['comment'].$divider;
+					}
+				}
+			}
+			$mod_vars = array(
+				'page_link' => $res['link'], // use direct link to news-item
+				'page_link_target' => "",
+				'page_title' => $func_page_title,
+				'page_description' => $res['title'], // use news-title as description
+				'page_modified_when' => $res['posted_when'],
+				'page_modified_by' => $res['posted_by'],
+				'text' => $text,
+				'max_excerpt_num' => $max_excerpt_num
+			);
+			if(print_excerpt2($mod_vars, $func_vars)) {
+				$result = true;
+			}
+		}
+	}
+	
+	// now fetch group-titles - ignore those without (active) postings
+	$table_groups = TABLE_PREFIX."mod_news_groups";
+	$table_posts = TABLE_PREFIX."mod_news_posts";
+	$query = $func_database->query("
+		SELECT DISTINCT g.title, g.group_id
+		FROM $table_groups AS g INNER JOIN $table_posts AS p ON g.group_id = p.group_id
+		WHERE g.section_id='$func_section_id' AND g.active = '1' AND p.active = '1'
+	");
+	// now call print_excerpt() for every single group, too
+	if($query->numRows() > 0) {
+		while($res = $query->fetchRow()) {
+			$mod_vars = array(
+				'page_link' => $func_page_link,
+				'page_link_target' => "&g=".$res['group_id'],
+				'page_title' => $func_page_title,
+				'page_description' => $func_page_description,
+				'page_modified_when' => $func_page_modified_when,
+				'page_modified_by' => $func_page_modified_by,
+				'text' => $res['title'].$divider,
+				'max_excerpt_num' => $max_excerpt_num
+			);
+			if(print_excerpt2($mod_vars, $func_vars)) {
+				$result = true;
+			}
+		}
+	}
+	return $result;
+}
+
+?>
Index: branches/2.8.x/wb/modules/news/comment_page.php
===================================================================
--- branches/2.8.x/wb/modules/news/comment_page.php	(revision 1419)
+++ branches/2.8.x/wb/modules/news/comment_page.php	(revision 1420)
@@ -1,131 +1,129 @@
-<?php
-/**
- *
- * @category        modules
- * @package         news
- * @author          WebsiteBaker Project
- * @copyright       2004-2009, Ryan Djurovich
- * @copyright       2009-2011, Website Baker Org. e.V.
- * @link			http://www.websitebaker2.org/
- * @license         http://www.gnu.org/licenses/gpl.html
- * @platform        WebsiteBaker 2.8.x
- * @requirements    PHP 5.2.2 and higher
- * @version         $Id$
- * @filesource		$HeadURL$
- * @lastmodified    $Date$
- *
- */
-
-// Make sure page cannot be accessed directly
-if(!defined('WB_URL')) {
-	header('Location: ../index.php');
-	exit(0);
-}
-
-/* check if frontend.css file needs to be included into the <body></body> of page  */
-if ( (!function_exists('register_frontend_modfiles') || !defined('MOD_FRONTEND_CSS_REGISTERED')) && file_exists(WB_PATH .'/modules/news/frontend.css')) {
-	echo '<style type="text/css">';
-	include(WB_PATH .'/modules/news/frontend.css');
-	echo "\n</style>\n";
-}
-
-// check if module language file exists for the language set by the user (e.g. DE, EN)
-if(!file_exists(WB_PATH .'/modules/news/languages/'.LANGUAGE .'.php'))
-{
-	// no module language file exists for the language set by the user, include default module language file EN.php
-	require_once(WB_PATH .'/modules/news/languages/EN.php');
-}
-else
-{
-	// a module language file exists for the language defined by the user, load it
-	require_once(WB_PATH .'/modules/news/languages/'.LANGUAGE .'.php');
-}
-
-require_once(WB_PATH.'/include/captcha/captcha.php');
-
-// Get comments page template details from db
-$query_settings = $database->query("SELECT comments_page,use_captcha,commenting FROM ".TABLE_PREFIX."mod_news_settings WHERE section_id = '".SECTION_ID."'");
-if($query_settings->numRows() == 0)
-{
-	header("Location: ".WB_URL.PAGES_DIRECTORY."");
-	exit( 0 );
-}
-else
-{
-	$settings = $query_settings->fetchRow();
-
-	// Print comments page
-	$vars = array('[POST_TITLE]','[TEXT_COMMENT]');
-	$values = array(POST_TITLE, $MOD_NEWS['TEXT_COMMENT']);
-	echo str_replace($vars, $values, ($settings['comments_page']));
-	?>
-	<form name="comment" action="<?php echo WB_URL.'/modules/news/submit_comment.php?page_id='.PAGE_ID.'&amp;section_id='.SECTION_ID.'&amp;post_id='.POST_ID; ?>" method="post">
-	<?php if(ENABLED_ASP) { // add some honeypot-fields
-	?>
-	<input type="hidden" name="submitted_when" value="<?php $t=time(); echo $t; $_SESSION['submitted_when']=$t; ?>" />
-	<p class="nixhier">
-	email address:
-	<label for="email">Leave this field email blank:</label>
-	<input id="email" name="email" size="60" value="" /><br />
-	Homepage:
-	<label for="homepage">Leave this field homepage blank:</label>
-	<input id="homepage" name="homepage" size="60" value="" /><br />
-	URL:
-	<label for="url">Leave this field url blank:</label>
-	<input id="url" name="url" size="60" value="" /><br />
-	Comment:
-	<label for="comment">Leave this field comment blank:</label>
-	<input id="comment" name="comment" size="60" value="" /><br />
-	</p>
-	<?php }
-	echo $admin->getFTAN(); 
-	echo $TEXT['TITLE']; ?>:
-	<br />
-	<input type="text" name="title" maxlength="255" style="width: 90%;"<?php if(isset($_SESSION['comment_title'])) { echo ' value="'.$_SESSION['comment_title'].'"'; unset($_SESSION['comment_title']); } ?> />
-	<br /><br />
-	<?php echo $TEXT['COMMENT']; 
-	?>:
-	<br />
-	<?php if(ENABLED_ASP) { ?>
-		<textarea name="comment_<?php echo date('W'); ?>" rows="10" cols="1" style="width: 90%; height: 150px;"><?php if(isset($_SESSION['comment_body'])) { echo $_SESSION['comment_body']; unset($_SESSION['comment_body']); } ?></textarea>
-	<?php } else { ?>
-		<textarea name="comment" rows="10" cols="1" style="width: 90%; height: 150px;"><?php if(isset($_SESSION['comment_body'])) { echo $_SESSION['comment_body']; unset($_SESSION['comment_body']); } ?></textarea>
-	<?php } ?>
-	<br /><br />
-	<?php
-	if(isset($_SESSION['captcha_error'])) {
-		echo '<font color="#FF0000">'.$_SESSION['captcha_error'].'</font><br />';
-		$_SESSION['captcha_retry_news'] = true;
-	}
-	// Captcha
-	if($settings['use_captcha']) {
-	?>
-	<table cellpadding="2" cellspacing="0" border="0">
-	<tr>
-		<td><?php echo $TEXT['VERIFICATION']; ?>:</td>
-		<td><?php call_captcha(); ?></td>
-	</tr>
-    </table>
-	<?php
-	if(isset($_SESSION['captcha_error'])) {
-		unset($_SESSION['captcha_error']);
-		?><script>document.comment.captcha.focus();</script><?php
-	}?>
-	<?php
-	}
-	?>
-	<table class="news-table">
-	<tr>
-	    <td>
-            <input type="submit" name="submit" value="<?php echo $MOD_NEWS['TEXT_ADD_COMMENT']; ?>" />
-        </td>
-        <td>
-		    <input type="button" value="<?php echo $TEXT['CANCEL']; ?>" onclick="history.go(-1)"  />
-        </td>
-	</tr>
-    </table>
-	</form>
-	<?php
-}
-
+<?php
+/**
+ *
+ * @category        modules
+ * @package         news
+ * @author          WebsiteBaker Project
+ * @copyright       2004-2009, Ryan Djurovich
+ * @copyright       2009-2011, Website Baker Org. e.V.
+ * @link			http://www.websitebaker2.org/
+ * @license         http://www.gnu.org/licenses/gpl.html
+ * @platform        WebsiteBaker 2.8.x
+ * @requirements    PHP 5.2.2 and higher
+ * @version         $Id$
+ * @filesource		$HeadURL$
+ * @lastmodified    $Date$
+ *
+ */
+
+
+// Must include code to stop this file being access directly
+if(defined('WB_PATH') == false) { die("Cannot access this file directly"); }
+
+/* check if frontend.css file needs to be included into the <body></body> of page  */
+if ( (!function_exists('register_frontend_modfiles') || !defined('MOD_FRONTEND_CSS_REGISTERED')) && file_exists(WB_PATH .'/modules/news/frontend.css')) {
+	echo '<style type="text/css">';
+	include(WB_PATH .'/modules/news/frontend.css');
+	echo "\n</style>\n";
+}
+
+// check if module language file exists for the language set by the user (e.g. DE, EN)
+if(!file_exists(WB_PATH .'/modules/news/languages/'.LANGUAGE .'.php'))
+{
+	// no module language file exists for the language set by the user, include default module language file EN.php
+	require_once(WB_PATH .'/modules/news/languages/EN.php');
+}
+else
+{
+	// a module language file exists for the language defined by the user, load it
+	require_once(WB_PATH .'/modules/news/languages/'.LANGUAGE .'.php');
+}
+
+require_once(WB_PATH.'/include/captcha/captcha.php');
+
+// Get comments page template details from db
+$query_settings = $database->query("SELECT comments_page,use_captcha,commenting FROM ".TABLE_PREFIX."mod_news_settings WHERE section_id = '".SECTION_ID."'");
+if($query_settings->numRows() == 0)
+{
+	header("Location: ".WB_URL.PAGES_DIRECTORY."");
+	exit( 0 );
+}
+else
+{
+	$settings = $query_settings->fetchRow();
+
+	// Print comments page
+	$vars = array('[POST_TITLE]','[TEXT_COMMENT]');
+	$values = array(POST_TITLE, $MOD_NEWS['TEXT_COMMENT']);
+	echo str_replace($vars, $values, ($settings['comments_page']));
+	?>
+	<form name="comment" action="<?php echo WB_URL.'/modules/news/submit_comment.php?page_id='.PAGE_ID.'&amp;section_id='.SECTION_ID.'&amp;post_id='.POST_ID; ?>" method="post">
+	<?php if(ENABLED_ASP) { // add some honeypot-fields
+	?>
+	<input type="hidden" name="submitted_when" value="<?php $t=time(); echo $t; $_SESSION['submitted_when']=$t; ?>" />
+	<p class="nixhier">
+	email address:
+	<label for="email">Leave this field email blank:</label>
+	<input id="email" name="email" size="60" value="" /><br />
+	Homepage:
+	<label for="homepage">Leave this field homepage blank:</label>
+	<input id="homepage" name="homepage" size="60" value="" /><br />
+	URL:
+	<label for="url">Leave this field url blank:</label>
+	<input id="url" name="url" size="60" value="" /><br />
+	Comment:
+	<label for="comment">Leave this field comment blank:</label>
+	<input id="comment" name="comment" size="60" value="" /><br />
+	</p>
+	<?php }
+	echo $admin->getFTAN(); 
+	echo $TEXT['TITLE']; ?>:
+	<br />
+	<input type="text" name="title" maxlength="255" style="width: 90%;"<?php if(isset($_SESSION['comment_title'])) { echo ' value="'.$_SESSION['comment_title'].'"'; unset($_SESSION['comment_title']); } ?> />
+	<br /><br />
+	<?php echo $TEXT['COMMENT']; 
+	?>:
+	<br />
+	<?php if(ENABLED_ASP) { ?>
+		<textarea name="comment_<?php echo date('W'); ?>" rows="10" cols="1" style="width: 90%; height: 150px;"><?php if(isset($_SESSION['comment_body'])) { echo $_SESSION['comment_body']; unset($_SESSION['comment_body']); } ?></textarea>
+	<?php } else { ?>
+		<textarea name="comment" rows="10" cols="1" style="width: 90%; height: 150px;"><?php if(isset($_SESSION['comment_body'])) { echo $_SESSION['comment_body']; unset($_SESSION['comment_body']); } ?></textarea>
+	<?php } ?>
+	<br /><br />
+	<?php
+	if(isset($_SESSION['captcha_error'])) {
+		echo '<font color="#FF0000">'.$_SESSION['captcha_error'].'</font><br />';
+		$_SESSION['captcha_retry_news'] = true;
+	}
+	// Captcha
+	if($settings['use_captcha']) {
+	?>
+	<table cellpadding="2" cellspacing="0" border="0">
+	<tr>
+		<td><?php echo $TEXT['VERIFICATION']; ?>:</td>
+		<td><?php call_captcha(); ?></td>
+	</tr>
+    </table>
+	<?php
+	if(isset($_SESSION['captcha_error'])) {
+		unset($_SESSION['captcha_error']);
+		?><script>document.comment.captcha.focus();</script><?php
+	}?>
+	<?php
+	}
+	?>
+	<table class="news-table">
+	<tr>
+	    <td>
+            <input type="submit" name="submit" value="<?php echo $MOD_NEWS['TEXT_ADD_COMMENT']; ?>" />
+        </td>
+        <td>
+		    <input type="button" value="<?php echo $TEXT['CANCEL']; ?>" onclick="history.go(-1)"  />
+        </td>
+	</tr>
+    </table>
+	</form>
+	<?php
+}
+
 ?>
\ No newline at end of file
