Project

General

Profile

« Previous | Next » 

Revision 1626

Added by darkviper over 12 years ago

started rebuild and reorganize the OutputFilter-System

View differences:

branches/2.8.x/CHANGELOG
11 11
! = Update/Change
12 12
===============================================================================
13 13

  
14
29 Feb-2012 Build 1626 Werner v.d.Decken(DarkViper)
15
! started rebuild and reorganize the OutputFilter-System
14 16
29 Feb-2012 Build 1625 Dietmar Woellbrink (Luisehahne)
15 17
! update correct_theme_source and fixed the call in all files
16 18
29 Feb-2012 Build 1624 Dietmar Woellbrink (Luisehahne)
branches/2.8.x/wb/admin/interface/version.php
51 51

  
52 52
// check if defined to avoid errors during installation (redirect to admin panel fails if PHP error/warnings are enabled)
53 53
if(!defined('VERSION')) define('VERSION', '2.8.3');
54
if(!defined('REVISION')) define('REVISION', '1625');
54
if(!defined('REVISION')) define('REVISION', '1626');
55 55
if(!defined('SP')) define('SP', '');
branches/2.8.x/wb/index.php
122 122
require(WB_PATH.'/templates/'.TEMPLATE.'/index.php');
123 123
$output = ob_get_contents();
124 124
if(ob_get_length() > 0) { ob_end_clean(); }
125

  
126
// wb->preprocess() -- replace all [wblink123] with real, internal links
127
if( method_exists($wb, 'preprocess') )
128
{
129
   $wb->preprocess($output);
130
}
131

  
132
// Load Droplet engine and process
133
	if(file_exists(WB_PATH .'/modules/droplets/droplets.php')) {
134
		include_once(WB_PATH .'/modules/droplets/droplets.php');
135
		if(function_exists('evalDroplets')) {
136
			$output = evalDroplets($output);
137
		}
138
	}
139

  
140
// Load backwards compatible frontend filter support and process
141
	if(file_exists(WB_PATH .'/modules/output_filter/filter-routines.php')) {
142
		include_once(WB_PATH .'/modules/output_filter/filter-routines.php');
125
// execute frontend output filters
126
	if(file_exists(WB_PATH .'/modules/output_filter/index.php')) {
127
		include_once(WB_PATH .'/modules/output_filter/index.php');
143 128
		if(function_exists('executeFrontendOutputFilter')) {
144 129
			$output = executeFrontendOutputFilter($output);
145
		}elseif(function_exists('filter_frontend_output')) {
146
			$output = filter_frontend_output($output);
147 130
		}
148

  
149 131
	}
150

  
151
// move css definitions into head section
152
	if(function_exists('moveCssToHead')) {
153
		$output = moveCssToHead($output);
154
	}
155 132
// now send complete page to the browser
156 133
echo $output;
157 134
// end of wb-script
branches/2.8.x/wb/modules/output_filter/filter-routines.php
14 14
 * @lastmodified    $Date$
15 15
 *
16 16
 */
17
/* -------------------------------------------------------- */
18
// Must include code to stop this file being accessed directly
19
require_once( dirname(dirname(dirname(__FILE__))).'/framework/globalExceptionHandler.php');
20
if(!defined('WB_PATH')) { throw new IllegalFileException(); }
21
/* -------------------------------------------------------- */
22

  
23
/* ************************************************************************** */
24
/**
25
 * execute the frontend output filter to modify email addresses
26
 * @param string actual content
27
 * @return string modified content
28
 */
29
	function executeFrontendOutputFilter($content) {
30
		// get output filter settings from database
31
		$filter_settings = getOutputFilterSettings();
32
		$output_filter_mode = 0;
33
		$output_filter_mode |= ($filter_settings['email_filter'] * pow(2, 0));  // n | 2^0
34
		$output_filter_mode |= ($filter_settings['mailto_filter'] * pow(2, 1)); // n | 2^1
35
		define('OUTPUT_FILTER_AT_REPLACEMENT', $filter_settings['at_replacement']);
36
		define('OUTPUT_FILTER_DOT_REPLACEMENT', $filter_settings['dot_replacement']);
37
/* ### filter type: protect email addresses ################################# */
38
		if( ($output_filter_mode & pow(2, 0)) || ($output_filter_mode & pow(2, 1)) ) {
39
			$content = _doFilterEmail($content, $output_filter_mode);
40
		}
41
/* ### filter type: full qualified URLs ##################################### */
42
        if($filter_settings['sys_rel'] == 1){
43
			$content = _doFilterRelUrl($content);
44
		}
45
/* ### end of filters ####################################################### */
46
		return $content;
17
/* --- this is a wrapper for backward compatibility only --- */
18
	$sModuleDir = str_replace('\\', '/', dirname(__FILE__)).'/';
19
	if (file_exists($sModuleDir.'index.php')) {
20
		require($sModuleDir.'index.php');
47 21
	}
48
/* ************************************************************************** */
49
/**
50
 * function to read the current filter settings
51
 * @global object $database
52
 * @global object $admin
53
 * @param void
54
 * @return array contains all settings
55
 */
56
	function getOutputFilterSettings() {
57
		global $database, $admin;
58
	// set default values
59
		$settings = array(
60
			'sys_rel'         => 0,
61
			'email_filter'    => 0,
62
			'mailto_filter'   => 0,
63
			'at_replacement'  => '(at)',
64
			'dot_replacement' => '(dot)'
65
		);
66
	// be sure field 'sys_rel' is in table
67
		$database->field_add( TABLE_PREFIX.'mod_output_filter', 'sys_rel', 'INT NOT NULL DEFAULT \'0\' FIRST');
68
	// request settings from database
69
		$sql = 'SELECT * FROM `'.TABLE_PREFIX.'mod_output_filter';
70
		if(($res = $database->query($sql))) {
71
			if(($rec = $res->fetchRow())) {
72
				$settings = $rec;
73
				$settings['at_replacement']  = $admin->strip_slashes($settings['at_replacement']);
74
				$settings['dot_replacement'] = $admin->strip_slashes($settings['dot_replacement']);
75
			}
76
		}
77
	// return array with filter settings
78
		return $settings;
79
	}
80
/* ************************************************************************** */
81
/**
82
 * Convert full qualified, local URLs into relative URLs
83
 * @param string $content
84
 * @return string
85
 */
86
	function _doFilterRelUrl($content) {
87
		$content = preg_replace_callback(
88
				'/((?:href|src)\s*=\s*")([^\"]*?)(")/iU',
89
				create_function('$matches',
90
				    '$retval = $matches[0]; '.
91
		            '$h = parse_url($matches[2], PHP_URL_HOST); '.
92
					'if(isset($h) && $h != \'\') { '.
93
					'if(stripos(WB_URL, $h) !== false) { '.
94
					'$a = parse_url($matches[2]); '.
95
					'$p = (isset($a[\'path\']) ? $a[\'path\'] : \'\'); '.
96
					'$q = (isset($a[\'query\']) ? \'?\'.$a[\'query\'] : \'\'); '.
97
					'$f = (isset($a[\'fragment\']) ? \'#\'.$a[\'fragment\'] : \'\'); '.
98
					'$p .= ($q.$f); '.
99
					'$retval = $matches[1]."/".(isset($p) ? ltrim(str_replace("//", "/", $p), "/") : "").$matches[3]; '.
100
					'}} return $retval;'),
101
		        $content);
102
		return $content;
103
	}
104
/* ************************************************************************** */
105
/**
106
 * protect email addresses (replace '@' and '.' and obfuscate address
107
 * @param string $content
108
 * @return string
109
 */
110
	function _doFilterEmail($content, $output_filter_mode) {
111
	// test if js-decryption is installed
112
		if( preg_match('/<head.*<.*src=\".*\/mdcr.js.*>.*<\/head/siU', $content) ) {
113
			$output_filter_mode |= pow(2, 2); // n | 2^2
114
		}else {
115
		// try to insert js-decrypt into <head> if available
116
			$script = str_replace('\\', '/',str_replace(WB_PATH,'', dirname(__FILE__)).'/js/mdcr.js');
117
			if(is_readable(WB_PATH.$script)) {
118
				$scriptLink = '<script src="'.WB_URL.$script.'" type="text/javascript"></script>';
119
				$regex = '/(.*)(<\s*?\/\s*?head\s*>.*)/isU';
120
				$replace = '$1'.$scriptLink.'$2';
121
				$content = preg_replace ($regex, $replace, $content);
122
				$output_filter_mode |= pow(2, 2); // n | 2^2
123
			}
124
		}
125
	// define some constants so we do not call the database in the callback functions again
126
		define('OUTPUT_FILTER_MODE', (int)$output_filter_mode);
127
/* *** obfuscate mailto addresses by js:mdcr *** */
128
		// work out the defined output filter mode: possible output filter modes: [0], 1, 2, 3, 6, 7
129
		// 2^0 * (0.. disable, 1.. enable) filtering of mail addresses in text
130
		// 2^1 * (0.. disable, 1.. enable) filtering of mail addresses in mailto links
131
		// 2^2 * (0.. disable, 1.. enable) Javascript mailto encryption (only if mailto filtering enabled)
132

  
133
		// first search part to find all mailto email addresses
134
		$pattern = '#(<a[^<]*href\s*?=\s*?"\s*?mailto\s*?:\s*?)([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})([^"]*?)"([^>]*>)(.*?)</a>';
135
		// second part to find all non mailto email addresses
136
		$pattern .= '|(value\s*=\s*"|\')??\b([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})\b#i';
137
/*
138
	Sub 1:\b(<a.[^<]*href\s*?=\s*?"\s*?mailto\s*?:\s*?)			-->	"<a id="yyy" class="xxx" href = " mailto :" ignoring white spaces
139
	Sub 2:([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})			-->	the email address in the mailto: part of the mail link
140
	Sub 3:([^"]*?)"												--> possible ?Subject&cc... stuff attached to the mail address
141
	Sub 4:([^>]*>)												--> all class or id statements after the mailto but before closing ..>
142
	Sub 5:(.*?)</a>\b											--> the mailto text; all characters between >xxxxx</a>
143
	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)
144
*/
145
		// find all email addresses embedded in the content and filter them using a callback function
146
		$content = preg_replace_callback($pattern, '_cbDoExecuteFilter', $content);
147
		return $content;
148
	}
149
/* ************************************************************************** */
150
/**
151
 * callback-function for function _doFilterEmail() to proceed search results
152
 * @param array results from preg_replace
153
 * @return string proceeded replacement string
154
 */
155
	function _cbDoExecuteFilter($match) {
156
		// check if required arguments are defined
157
		if(!( defined('OUTPUT_FILTER_MODE')
158
		      && defined('OUTPUT_FILTER_AT_REPLACEMENT')
159
		      && defined('OUTPUT_FILTER_MODE')
160
    	    ) ) {
161
			return $match[0];
162
		}
163
		$search = array('@', '.');
164
		$replace = array(OUTPUT_FILTER_AT_REPLACEMENT ,OUTPUT_FILTER_DOT_REPLACEMENT);
165
		// check if the match contains the expected number of subpatterns (6|8)
166
		switch (count($match)) {
167
			case 8:
168
			/** OUTPUT FILTER FOR EMAIL ADDRESSES EMBEDDED IN TEXT **/
169
			// 1.. text mails only, 3.. text mails + mailto (no JS), 7 text mails + mailto (JS)
170
				if(!in_array(OUTPUT_FILTER_MODE, array(1,3,7))) return $match[0];
171
				// do not filter mail addresses included in input tags (<input ... value = "test@mail)
172
				if (strpos($match[6], 'value') !== false) return $match[0];
173
				// filtering of non mailto email addresses enabled
174
				return str_replace($search, $replace, $match[0]);
175
			break;
176
			case 6:
177
			/** OUTPUT FILTER FOR EMAIL ADDRESSES EMBEDDED IN MAILTO LINKS **/
178
			// 2.. mailto only (no JS), 3.. text mails + mailto (no JS), 6.. mailto only (JS), 7.. all filters active
179
				if(!in_array(OUTPUT_FILTER_MODE, array(2,3,6,7))) return $match[0];
180
				// check if last part of the a href link: >xxxx</a> contains a email address we need to filter
181
				$pattern = '#[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}#i';
182
				if(preg_match_all($pattern, $match[5], $matches)) {
183
					foreach($matches as $submatch) {
184
						foreach($submatch as $value) {
185
						// replace all . and all @ in email address parts by (dot) and (at) strings
186
							$match[5] = str_replace($value, str_replace($search, $replace, $value), $match[5]);
187
						}
188
					}
189
				}
190
				// check if Javascript encryption routine is enabled
191
				if(in_array(OUTPUT_FILTER_MODE, array(6,7))) {
192
				/** USE JAVASCRIPT ENCRYPTION FOR MAILTO LINKS **/
193
				// extract possible class and id attribute from ahref link
194
					preg_match('/class\s*?=\s*?("|\')(.*?)\1/ix', $match[0], $class_attr);
195
					$class_attr = empty($class_attr) ? '' : 'class="' . $class_attr[2] . '" ';
196
					preg_match('/id\s*?=\s*?("|\')(.*?)\1/ix', $match[0], $id_attr);
197
					$id_attr = empty($id_attr) ? '' : 'id="' . $id_attr[2] . '" ';
198
				// preprocess mailto link parts for further usage
199
					$search = array('@', '.', '_', '-'); $replace = array('F', 'Z', 'X', 'K');
200
					$email_address = str_replace($search, $replace, strtolower($match[2]));
201
					$email_subject = rawurlencode(html_entity_decode($match[3]));
202
				// create a random encryption key for the Caesar cipher
203
					mt_srand((double)microtime()*1000000);	// (PHP < 4.2.0)
204
					$shift = mt_rand(1, 25);
205
				// encrypt the email using an adapted Caesar cipher
206
					$encrypted_email = "";
207
					for($i = strlen($email_address) -1; $i > -1; $i--) {
208
						if(preg_match('#[FZXK0-9]#', $email_address[$i], $characters)) {
209
							$encrypted_email .= $email_address[$i];
210
						} else {
211
							$encrypted_email .= chr((ord($email_address[$i]) -97 + $shift) % 26 + 97);
212
						}
213
					}
214
					$encrypted_email .= chr($shift + 97);
215
				// build the encrypted Javascript mailto link
216
					$mailto_link  = "<a {$class_attr}{$id_attr}href=\"javascript:mdcr('$encrypted_email','$email_subject')\">" .$match[5] ."</a>";
217
					return $mailto_link;
218
				} else {
219
				/** DO NOT USE JAVASCRIPT ENCRYPTION FOR MAILTO LINKS **/
220
				// as minimum protection, replace @ in the mailto part by (at)
221
				// dots are not transformed as this would transform my.name@domain.com into: my(dot)name(at)domain(dot)com
222
				// rebuild the mailto link from the subpatterns (at the missing characters " and </a>")
223
					return $match[1] .str_replace('@', OUTPUT_FILTER_AT_REPLACEMENT, $match[2]) .$match[3] .'"' .$match[4] .$match[5] .'</a>';
224
				// if you want to protect both, @ and dots, comment out the line above and remove the comment from the line below
225
				// return $match[1] .str_replace($search, $replace, $match[2]) .$match[3] .'"' .$match[4] .$match[5] .'</a>';
226
				}
227
			break;
228
			default:
229
		// number of subpatterns do not match the requirements ... do nothing
230
				return $match[0];
231
			break;
232
		}
233
	}
234
/* ************************************************************************** */
branches/2.8.x/wb/modules/output_filter/info.php
18 18
$module_directory = 'output_filter';
19 19
$module_name = 'Frontend Output Filter';
20 20
$module_function = 'tool';
21
$module_version	= '0.3';
22
$module_platform = '2.8.2';
21
$module_version	= '0.4';
22
$module_platform = '2.8.3';
23 23
$module_author = 'Christian Sommer(doc), WB-Project, Werner v.d. Decken(DarkViper)';
24 24
$module_license = 'GNU General Public License';
25 25
$module_description = 'This module allows to filter the output before displaying it on the frontend. Support for filtering mailto links and mail addresses in strings.';
branches/2.8.x/wb/modules/output_filter/filters/filterRelUrl.php
1
<?php
2
/**
3
 * Convert full qualified, local URLs into relative URLs
4
 * @param string $content
5
 * @return string
6
 */
7
	function doFilterRelUrl($content) {
8
		$content = preg_replace_callback(
9
				'/((?:href|src)\s*=\s*")([^\"]*?)(")/iU',
10
				create_function('$matches',
11
				    '$retval = $matches[0]; '.
12
		            '$h = parse_url($matches[2], PHP_URL_HOST); '.
13
					'if(isset($h) && $h != \'\') { '.
14
					'if(stripos(WB_URL, $h) !== false) { '.
15
					'$a = parse_url($matches[2]); '.
16
					'$p = (isset($a[\'path\']) ? $a[\'path\'] : \'\'); '.
17
					'$q = (isset($a[\'query\']) ? \'?\'.$a[\'query\'] : \'\'); '.
18
					'$f = (isset($a[\'fragment\']) ? \'#\'.$a[\'fragment\'] : \'\'); '.
19
					'$p .= ($q.$f); '.
20
					'$retval = $matches[1]."/".(isset($p) ? ltrim(str_replace("//", "/", $p), "/") : "").$matches[3]; '.
21
					'}} return $retval;'),
22
		        $content);
23
		return $content;
24
	}
25

  
26
?>
0 27

  
branches/2.8.x/wb/modules/output_filter/filters/filterWbLink.php
1
<?php
2
/*
3
 * replace all "[wblink{page_id}]" with real links
4
 * @param string &$content : reference to global $content
5
 * @return void
6
 * @history 100216 17:00:00 optimise errorhandling, speed, SQL-strict
7
 */
8
	function doFilterWbLink($content)
9
	{
10
		global $database, $wb;
11
		$replace_list = array();
12
		$pattern = '/\[wblink([0-9]+)\]/isU';
13
		if(preg_match_all($pattern,$content,$ids))
14
		{
15
			foreach($ids[1] as $key => $page_id) {
16
				$replace_list[$page_id] = $ids[0][$key];
17
			}
18
			foreach($replace_list as $page_id => $tag)
19
			{
20
				$sql = 'SELECT `link` FROM `'.TABLE_PREFIX.'pages` WHERE `page_id` = '.(int)$page_id;
21
				$link = $database->get_one($sql);
22
				if(!is_null($link)) {
23
					$link = $wb->page_link($link);
24
					$content = str_replace($tag, $link, $content);
25
				}
26
			}
27
		}
28
		return $content;
29
	}
0 30

  
branches/2.8.x/wb/modules/output_filter/filters/filterEmail.php
1
<?php
2
/**
3
 * protect email addresses (replace '@' and '.' and obfuscate address
4
 * @param string $content
5
 * @return string
6
 */
7
	function doFilterEmail($content, $output_filter_mode) {
8
	// test if js-decryption is installed
9
		if( preg_match('/<head.*<.*src=\".*\/mdcr.js.*>.*<\/head/siU', $content) ) {
10
			$output_filter_mode |= pow(2, 2); // n | 2^2
11
		}else {
12
		// try to insert js-decrypt into <head> if available
13
			$script = str_replace('\\', '/',str_replace(WB_PATH,'', dirname(__FILE__)).'/js/mdcr.js');
14
			if(is_readable(WB_PATH.$script)) {
15
				$scriptLink = '<script src="'.WB_URL.$script.'" type="text/javascript"></script>';
16
				$regex = '/(.*)(<\s*?\/\s*?head\s*>.*)/isU';
17
				$replace = '$1'.$scriptLink.'$2';
18
				$content = preg_replace ($regex, $replace, $content);
19
				$output_filter_mode |= pow(2, 2); // n | 2^2
20
			}
21
		}
22
	// define some constants so we do not call the database in the callback functions again
23
		define('OUTPUT_FILTER_MODE', (int)$output_filter_mode);
24
/* *** obfuscate mailto addresses by js:mdcr *** */
25
		// work out the defined output filter mode: possible output filter modes: [0], 1, 2, 3, 6, 7
26
		// 2^0 * (0.. disable, 1.. enable) filtering of mail addresses in text
27
		// 2^1 * (0.. disable, 1.. enable) filtering of mail addresses in mailto links
28
		// 2^2 * (0.. disable, 1.. enable) Javascript mailto encryption (only if mailto filtering enabled)
29

  
30
		// first search part to find all mailto email addresses
31
		$pattern = '#(<a[^<]*href\s*?=\s*?"\s*?mailto\s*?:\s*?)([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})([^"]*?)"([^>]*>)(.*?)</a>';
32
		// second part to find all non mailto email addresses
33
		$pattern .= '|(value\s*=\s*"|\')??\b([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})\b#i';
34
/*
35
	Sub 1:\b(<a.[^<]*href\s*?=\s*?"\s*?mailto\s*?:\s*?)			-->	"<a id="yyy" class="xxx" href = " mailto :" ignoring white spaces
36
	Sub 2:([A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4})			-->	the email address in the mailto: part of the mail link
37
	Sub 3:([^"]*?)"												--> possible ?Subject&cc... stuff attached to the mail address
38
	Sub 4:([^>]*>)												--> all class or id statements after the mailto but before closing ..>
39
	Sub 5:(.*?)</a>\b											--> the mailto text; all characters between >xxxxx</a>
40
	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)
41
*/
42
		// find all email addresses embedded in the content and filter them using a callback function
43
		$content = preg_replace_callback($pattern, '_cbDoExecuteFilter', $content);
44
		return $content;
45
	}
46
/* ************************************************************************** */
47
/**
48
 * callback-function for function _doFilterEmail() to proceed search results
49
 * @param array results from preg_replace
50
 * @return string proceeded replacement string
51
 */
52
	function _cbDoExecuteFilter($match) {
53
		// check if required arguments are defined
54
		if(!( defined('OUTPUT_FILTER_MODE')
55
		      && defined('OUTPUT_FILTER_AT_REPLACEMENT')
56
		      && defined('OUTPUT_FILTER_MODE')
57
    	    ) ) {
58
			return $match[0];
59
		}
60
		$search = array('@', '.');
61
		$replace = array(OUTPUT_FILTER_AT_REPLACEMENT ,OUTPUT_FILTER_DOT_REPLACEMENT);
62
		// check if the match contains the expected number of subpatterns (6|8)
63
		switch (count($match)) {
64
			case 8:
65
			/** OUTPUT FILTER FOR EMAIL ADDRESSES EMBEDDED IN TEXT **/
66
			// 1.. text mails only, 3.. text mails + mailto (no JS), 7 text mails + mailto (JS)
67
				if(!in_array(OUTPUT_FILTER_MODE, array(1,3,7))) return $match[0];
68
				// do not filter mail addresses included in input tags (<input ... value = "test@mail)
69
				if (strpos($match[6], 'value') !== false) return $match[0];
70
				// filtering of non mailto email addresses enabled
71
				return str_replace($search, $replace, $match[0]);
72
			break;
73
			case 6:
74
			/** OUTPUT FILTER FOR EMAIL ADDRESSES EMBEDDED IN MAILTO LINKS **/
75
			// 2.. mailto only (no JS), 3.. text mails + mailto (no JS), 6.. mailto only (JS), 7.. all filters active
76
				if(!in_array(OUTPUT_FILTER_MODE, array(2,3,6,7))) return $match[0];
77
				// check if last part of the a href link: >xxxx</a> contains a email address we need to filter
78
				$pattern = '#[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}#i';
79
				if(preg_match_all($pattern, $match[5], $matches)) {
80
					foreach($matches as $submatch) {
81
						foreach($submatch as $value) {
82
						// replace all . and all @ in email address parts by (dot) and (at) strings
83
							$match[5] = str_replace($value, str_replace($search, $replace, $value), $match[5]);
84
						}
85
					}
86
				}
87
				// check if Javascript encryption routine is enabled
88
				if(in_array(OUTPUT_FILTER_MODE, array(6,7))) {
89
				/** USE JAVASCRIPT ENCRYPTION FOR MAILTO LINKS **/
90
				// extract possible class and id attribute from ahref link
91
					preg_match('/class\s*?=\s*?("|\')(.*?)\1/ix', $match[0], $class_attr);
92
					$class_attr = empty($class_attr) ? '' : 'class="' . $class_attr[2] . '" ';
93
					preg_match('/id\s*?=\s*?("|\')(.*?)\1/ix', $match[0], $id_attr);
94
					$id_attr = empty($id_attr) ? '' : 'id="' . $id_attr[2] . '" ';
95
				// preprocess mailto link parts for further usage
96
					$search = array('@', '.', '_', '-'); $replace = array('F', 'Z', 'X', 'K');
97
					$email_address = str_replace($search, $replace, strtolower($match[2]));
98
					$email_subject = rawurlencode(html_entity_decode($match[3]));
99
				// create a random encryption key for the Caesar cipher
100
					mt_srand((double)microtime()*1000000);	// (PHP < 4.2.0)
101
					$shift = mt_rand(1, 25);
102
				// encrypt the email using an adapted Caesar cipher
103
					$encrypted_email = "";
104
					for($i = strlen($email_address) -1; $i > -1; $i--) {
105
						if(preg_match('#[FZXK0-9]#', $email_address[$i], $characters)) {
106
							$encrypted_email .= $email_address[$i];
107
						} else {
108
							$encrypted_email .= chr((ord($email_address[$i]) -97 + $shift) % 26 + 97);
109
						}
110
					}
111
					$encrypted_email .= chr($shift + 97);
112
				// build the encrypted Javascript mailto link
113
					$mailto_link  = "<a {$class_attr}{$id_attr}href=\"javascript:mdcr('$encrypted_email','$email_subject')\">" .$match[5] ."</a>";
114
					return $mailto_link;
115
				} else {
116
				/** DO NOT USE JAVASCRIPT ENCRYPTION FOR MAILTO LINKS **/
117
				// as minimum protection, replace @ in the mailto part by (at)
118
				// dots are not transformed as this would transform my.name@domain.com into: my(dot)name(at)domain(dot)com
119
				// rebuild the mailto link from the subpatterns (at the missing characters " and </a>")
120
					return $match[1] .str_replace('@', OUTPUT_FILTER_AT_REPLACEMENT, $match[2]) .$match[3] .'"' .$match[4] .$match[5] .'</a>';
121
				// if you want to protect both, @ and dots, comment out the line above and remove the comment from the line below
122
				// return $match[1] .str_replace($search, $replace, $match[2]) .$match[3] .'"' .$match[4] .$match[5] .'</a>';
123
				}
124
			break;
125
			default:
126
		// number of subpatterns do not match the requirements ... do nothing
127
				return $match[0];
128
			break;
129
		}
130
	}
0 131

  
branches/2.8.x/wb/modules/output_filter/filters/filterDroplets.php
1
<?php
2
/**
3
 * execute droplets
4
 * @param string $content
5
 * @return string 
6
 */
7
	function doFilterDroplets($content)
8
	{
9
		if(file_exists(WB_PATH .'/modules/droplets/droplets.php')) {
10
			include_once(WB_PATH .'/modules/droplets/droplets.php');
11
			if(function_exists('evalDroplets')) {
12
				$content = evalDroplets($content);
13
			}
14
		}
15
		return $content;
16
	}
0 17

  
branches/2.8.x/wb/modules/output_filter/filters/filterCssToHead.php
1
<?php
2
/**
3
 * moves all css definitions from <body> into <head> section
4
 * @param string $content
5
 * @return string
6
 */
7
	function doFilterCssToHead($content) {
8
		// move css definitions into head section
9
		$pattern1 = '/(?:<body.*?)(<link[^>]*?\"text\/css\".*?\/>)/si';
10
		$pattern2 = '/(?:<body.*?)(<style[^>]*?\"text\/css\"[^>]*?>.*?<\/style>)/si';
11
		while(preg_match($pattern1, $content, $matches)==1) {
12
		// loop through all linked CSS
13
			$insert = $matches[1];
14
			$content = str_replace($insert, '', $content);
15
			$insert = "\n".$insert."\n</head>\n<body";
16
			$content = preg_replace('/<\/head>.*?<body/si', $insert, $content);
17
		}
18
		while(preg_match($pattern2, $content, $matches)==1) {
19
		// loop through all inline CSS
20
			$insert = $matches[1];
21
			$content = str_replace($insert, '', $content);
22
			$insert = "\n".$insert."\n</head>\n<body";
23
			$content = preg_replace('/<\/head>.*?<body/si', $insert, $content);
24
		}
25
		return $content;
26
	}
0 27

  
branches/2.8.x/wb/modules/output_filter/index.php
4 4
 * @category        modules
5 5
 * @package         output_filter
6 6
 * @author          Christian Sommer, WB-Project, Werner v.d. Decken
7
 * @copyright       2009-2011, Website Baker Org. e.V.
7
 * @copyright       2011, Website Baker Org. e.V.
8 8
 * @link			http://www.websitebaker2.org/
9 9
 * @license         http://www.gnu.org/licenses/gpl.html
10 10
 * @platform        WebsiteBaker 2.8.2
......
14 14
 * @lastmodified    $Date$
15 15
 *
16 16
 */
17
/* -------------------------------------------------------- */
18
// Must include code to stop this file being accessed directly
19
require_once( dirname(dirname(dirname(__FILE__))).'/framework/globalExceptionHandler.php');
20
if(!defined('WB_PATH')) { throw new IllegalFileException(); }
21
/* -------------------------------------------------------- */
17 22

  
18
header('Location: ../index.php');
19
exit();
23
/* ************************************************************************** */
24
/**
25
 * execute the frontend output filter to modify email addresses
26
 * @param string actual content
27
 * @return string modified content
28
 */
29
	function executeFrontendOutputFilter($content) {
30
		// get output filter settings from database
31
		$filter_settings = getOutputFilterSettings();
32
		$sFilterDirectory = str_replace('\\', '/', dirname(__FILE__)).'/filters/';
33
		$output_filter_mode = 0;
34
		$output_filter_mode |= ($filter_settings['email_filter'] * pow(2, 0));  // n | 2^0
35
		$output_filter_mode |= ($filter_settings['mailto_filter'] * pow(2, 1)); // n | 2^1
36
		define('OUTPUT_FILTER_AT_REPLACEMENT', $filter_settings['at_replacement']);
37
		define('OUTPUT_FILTER_DOT_REPLACEMENT', $filter_settings['dot_replacement']);
38

  
39
/* ### filter type: execute droplets filter ################################# */
40
		if (file_exists($sFilterDirectory.'filterDroplets.php')) {
41
			require($sFilterDirectory.'filterDroplets.php');
42
			$content = doFilterDroplets($content);
43
		}
44
/* ### filter type: protect email addresses ################################# */
45
		if( ($output_filter_mode & pow(2, 0)) || ($output_filter_mode & pow(2, 1)) ) {
46
			if (file_exists($sFilterDirectory.'filterEmail.php')) {
47
				require($sFilterDirectory.'filterEmail.php');
48
				$content = doFilterEmail($content, $output_filter_mode);
49
			}
50
		}
51
/* ### filter type: change [wblinkxx] into real URLs ######################## */
52
		if (file_exists($sFilterDirectory.'filterWbLink.php')) {
53
			require($sFilterDirectory.'filterWbLink.php');
54
			$content = doFilterWbLink($content);
55
		}
56
/* ### filter type: full qualified URLs to relative URLs##################### */
57
        if($filter_settings['sys_rel'] == 1){
58
			if (file_exists($sFilterDirectory.'filterRelUrl.php')) {
59
				require($sFilterDirectory.'filterRelUrl.php');
60
				$content = doFilterRelUrl($content);
61
			}
62
		}
63
/* ### filter type: moves css definitions from <body> into <head> ########### */
64
		if (file_exists($sFilterDirectory.'filterCssToHead.php')) {
65
			require($sFilterDirectory.'filterCssToHead.php');
66
			$content = doFilterCssToHead($content);
67
		}
68

  
69
/* ### end of filters ####################################################### */
70
		return $content;
71
	}
72
/* ************************************************************************** */
73
/**
74
 * function to read the current filter settings
75
 * @global object $database
76
 * @global object $admin
77
 * @param void
78
 * @return array contains all settings
79
 */
80
	function getOutputFilterSettings() {
81
		global $database, $admin;
82
	// set default values
83
		$settings = array(
84
			'sys_rel'         => 0,
85
			'email_filter'    => 0,
86
			'mailto_filter'   => 0,
87
			'at_replacement'  => '(at)',
88
			'dot_replacement' => '(dot)'
89
		);
90
	// be sure field 'sys_rel' is in table
91
		$database->field_add( TABLE_PREFIX.'mod_output_filter', 'sys_rel', 'INT NOT NULL DEFAULT \'0\' FIRST');
92
	// request settings from database
93
		$sql = 'SELECT * FROM `'.TABLE_PREFIX.'mod_output_filter';
94
		if(($res = $database->query($sql))) {
95
			if(($rec = $res->fetchRow())) {
96
				$settings = $rec;
97
				$settings['at_replacement']  = $admin->strip_slashes($settings['at_replacement']);
98
				$settings['dot_replacement'] = $admin->strip_slashes($settings['dot_replacement']);
99
			}
100
		}
101
	// return array with filter settings
102
		return $settings;
103
	}
104
/* ************************************************************************** */

Also available in: Unified diff