This repository has been archived by the owner on Sep 21, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Ext404.php
285 lines (264 loc) · 9.23 KB
/
Ext404.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
<?php
/**
* Extended 404 Main Module file
*
* PHP version 5
*
* @category Contao
* @package Ext404
* @author Benjamin Meier <[email protected]>
* @copyright 2009-2012 Benjamin Meier
* @license http://www.gnu.org/licenses/gpl.html GNU/GPL
* @link https://github.com/b2m/ext404
*/
if (!defined('TL_ROOT')) die('You can not access this file directly!');
/**
* Class Ext404
*
* @category Contao
* @package Ext404
* @author Benjamin Meier <[email protected]>
* @copyright 2009-2012 Benjamin Meier
* @license http://www.gnu.org/licenses/gpl.html GNU/GPL
* @link https://github.com/b2m/ext404
*/
class Ext404 extends Module
{
/** @var string name of Template */
protected $strTemplate = 'ce_ext404';
/** @var string name of referer */
protected $referer = '';
/** @var string name of request */
protected $request = '';
/** @var boolean send mails */
protected $mail = true;
/** @var boolean log 404 */
protected $log = true;
/**
* Display a wildcard in the back end
*
* @return string
*/
public function generate()
{
if (TL_MODE == 'BE') {
$objTemplate = new BackendTemplate('be_wildcard');
$objTemplate->wildcard = '### Extended 404 ###';
$objTemplate->title = $this->headline;
return $objTemplate->parse();
}
return parent::generate();
}
/**
* Generate module
*
* @return nothing
*/
protected function compile()
{
// get file extension
$ext = pathinfo($this->Environment->requestUri, PATHINFO_EXTENSION);
// handling whitelist for file extensions
if (strlen($this->ext404_ext)>0) {
$this->handleExt($ext, $this->ext404_ext, $this->ext404_ext_handle);
}
// handling whitelist for file extensions for ie8
if (stripos($this->Environment->httpUserAgent, "msie 8.")!==false
&& strlen($this->ext404_ie8_ext)>0
) {
$this->handleExt(
$ext,
$this->ext404_ie8_ext,
$this->ext404_ie8_ext_handle
);
}
$this->referer = $this->Environment->http_referer;
$refhost = parse_url($this->referer, PHP_URL_HOST);
/* reverse IP-Lookup
* - check for -1 and false because of strange behaviour of ip2long
*/
if (ip2long($refhost)!=-1 && ip2long($refhost)!=false) {
$realhost = gethostbyaddr($refhost);
$this->referer = str_replace($refhost, $realhost, $this->referer);
$refhost = $realhost;
}
$this->request = $this->Environment->url.$this->Environment->requestUri;
// replace leading http and www parts
$search = "#^(http://){0,1}www([0-9]{0,1})\.#";
$this->referer = preg_replace($search, '', $this->referer);
$this->request = preg_replace($search, '', $this->request);
if ($this->referer=="" || $this->referer==$this->request) {
/* Case 1: Direct Call or wrong referer */
$this->Template->text = sprintf(
$GLOBALS['TL_LANG']['MSC']['ext404_text_case1'],
$this->request
);
} else {
// remove leading http and www parts
$referer_search = preg_replace($search, '', $refhost);
$referer_compare = preg_replace($search, '', $this->Environment->host);
if (strpos($referer_search, $referer_compare)===0) {
/* Case 2: Wrong Link on our website */
$this->Template->text = sprintf(
$GLOBALS['TL_LANG']['MSC']['ext404_text_case2'],
$this->request
);
if ($this->checkinform(
$GLOBALS['TL_LANG']['MSC']['ext404_email_own_error_subject'],
$GLOBALS['TL_LANG']['MSC']['ext404_email_own_error_text']
)
) {
$this->Template->addtext = $GLOBALS['TL_LANG']['MSC']['ext404_text_case2_informed'];
}
$this->entry();
} else {
/* Wrong Link with referer from somewhere else */
$searchengine = false;
$array = file(
$this->tl_root."system/modules/ext404/files/searchengines.txt"
);
$array = array_map("trim", $array);
foreach ($array as $search) {
$reg = "#^([a-z0-9\-\_\.]){0,}"
.preg_quote($search)."(\.([a-z]){2,3}){0,}$#";
if (preg_match($reg, $referer_search)) {
$searchengine = true;
break;
}
}
if ($searchengine) {
/* Case 3: Wrong Link from searchengine */
$this->Template->text = sprintf(
$GLOBALS['TL_LANG']['MSC']['ext404_text_case3'],
$this->request
);
} else {
/* Case 4: Wrong Link from other website */
$this->Template->text = sprintf(
$GLOBALS['TL_LANG']['MSC']['ext404_text_case4'],
$this->request
);
if ($this->checkinform(
$GLOBALS['TL_LANG']['MSC']['ext404_email_other_error_subject'],
$GLOBALS['TL_LANG']['MSC']['ext404_email_other_error_text']
)
) {
$this->Template->addtext = $GLOBALS['TL_LANG']['MSC']['ext404_text_case4_informed'];
}
$this->entry();
}
}
}
}
/**
* Sends an information mail
*
* @param string $subject Subject of email
* @param string $text Content of email
*
* @return boolean true if sending email was successfull
*/
protected function inform($subject, $text)
{
$this->import('Email');
$mail = new Email();
$mail->from = $this->ext404_email_from;
$mail->subject = sprintf($subject, $this->Environment->host);
$mail->text = sprintf($text, $this->request, $this->referer) . "\n";
return $mail->sendTo($this->ext404_email_to);
}
/**
* Checks the configuration if information via email is allowed
*
* @param string $subject Subject of email
* @param string $text Content of email
*
* @return boolean true if the informed message should be shown
*/
protected function checkinform($subject, $text)
{
if ($this->checktable()) {
if ($this->ext404_email_from=="" || $this->ext404_email_to=="") {
return false;
} else {
return true;
}
} else if ($this->ext404_email_from!="" && $this->ext404_email_to!="") {
return $this->inform($subject, $text);
}
}
/**
* Checks the database for already existing entries
*
* @return boolean true if there already was a request in the last 31 days
*/
protected function checktable()
{
// only inform once per month on double entries
$stamp = time()-31*7*24*60*60;
$query = "SELECT id FROM tl_ext404_log WHERE page=? ";
$query.= "AND referer=? AND tstamp >?";
$check = $this->Database->prepare($query)
->limit(1)
->execute($this->request, $this->referer, $stamp);
if ($check->numRows>0) {
return true;
} else {
return false;
}
}
/**
* Creates the database entry
*
* @return nothing
*/
protected function entry()
{
if ($this->log) {
$db_entry = array(
'page' => $this->request,
'referer' => $this->referer,
'tstamp' => time()
);
$this->Database->prepare("INSERT INTO tl_ext404_log %s")
->set($db_entry)
->execute();
}
}
/**
* Handles special cases
*
* @param string $ext Extension of current request
* @param string $extensions Comma separated whitelist of file extensions
* @param string $handle Handle for handling file extensions not in whitelist
*
* @return nothing
*/
protected function handleExt($ext, $extensions, $handle)
{
$extensions = array_map('trim', explode(',', $extensions));
// if first keyword is 'blacklist', list is used as blacklist
if ($extensions[0]=='blacklist' && in_array($ext, $extensions)
|| $extensions[0]!='blacklist' && !in_array($ext, $extensions)
) {
switch ($handle) {
case "nomail":
$this->mail = false;
break;
case "nolog":
$this->log = false;
break;
case "nomailnolog":
$this->mail = false;
$this->log = false;
break;
default:
header('HTTP/1.1 404 Page not found');
die('Page not found');
exit;
break;
}
}
}
}
?>