1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* This will generate a comments system for you in no time... |
6
|
|
|
* It includes an installed build in so all you have to do is upload the class file run a few commands |
7
|
|
|
* and you are ready to go :) |
8
|
|
|
* The intention is to make this a stand alone class so we are using ``mysqli`` to handle the mysql interactions |
9
|
|
|
* therefor you will need to pass your mysql details also |
10
|
|
|
* @author Mihai Ionut Vilcu ([email protected]) |
11
|
|
|
* July-2013 |
12
|
|
|
*/ |
13
|
|
|
class Comments_System |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* Default settings |
17
|
|
|
* @var array |
18
|
|
|
*/ |
19
|
|
|
var $settings = array( |
20
|
|
|
'comments_table' => '_comments', // the name of the table in which the comments will be hold |
21
|
|
|
'banned_table' => '_banned', // the name of the table in which the comments will be hold |
22
|
|
|
'auto_install' => true, // if the class is not already installed it will attempt to install it |
23
|
|
|
'public' => true, // if true unregistered users are allowed to post a comment |
24
|
|
|
'optional_email' => false, // if true users don't need to enter a valid email |
25
|
|
|
'isAdmin' => false, // if true some extra options are displyed delete |
26
|
|
|
'adminStyle' => array( // special formating to admin messages |
27
|
|
|
'username' => 'color: #0000ff; font-weidth: bold;', |
28
|
|
|
'box' => 'background-color: #FFFCDD' |
29
|
|
|
), |
30
|
|
|
'user_details' => array( // if public is false we use this user details to the added message |
31
|
|
|
'name' => 'user', |
32
|
|
|
'email' => '[email protected]', |
33
|
|
|
), |
34
|
|
|
'sort' => 'ORDER BY `id` DESC', // the sort, this is pasted as is so make sure it is parsed |
35
|
|
|
); |
36
|
|
|
var $link; // it will hold the mysql connection |
37
|
|
|
var $error = false; // it will hold an error message if any |
38
|
|
|
var $success = false; // it will hold an success message if any |
39
|
|
|
var $tmp = false; // it will carry some temporary data |
40
|
|
|
var $ignore = array('comm_edit', 'comm_del', 'comm_reply', 'comm_ban', 'comm_unban'); // keep the url clean |
41
|
|
|
var $checked_ips = array(); // will hold the ips checked if banned or not |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* setup the mysql connction and some settings |
45
|
|
|
* @param array $db_details contains the database details |
46
|
|
|
* @param array $settings settings to overwrite the default ones |
47
|
|
|
*/ |
48
|
|
|
function __construct($db_details, $settings = array()) |
|
|
|
|
49
|
|
|
{ |
50
|
|
|
if (session_id() == '') |
51
|
|
|
session_start(); |
52
|
|
|
|
53
|
|
|
// we first manage the mysql connection |
54
|
|
|
$this->link = @mysqli_connect($db_details['db_host'], $db_details['db_user'], $db_details['db_pass']); |
|
|
|
|
55
|
|
|
|
56
|
|
|
if (!$this->link) die('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error()); |
|
|
|
|
57
|
|
|
|
58
|
|
|
mysqli_select_db($this->link, $db_details['db_name']) or die(mysqli_error($this->link)); |
|
|
|
|
59
|
|
|
|
60
|
|
|
// we add the new settings if any |
61
|
|
|
$this->settings = array_merge($this->settings, $settings); |
62
|
|
|
|
63
|
|
|
$this->settings['comments_table'] = str_replace("`", "``", $this->settings['comments_table']); |
64
|
|
|
|
65
|
|
|
// auto install |
66
|
|
|
if ($this->settings['auto_install'] && !@mysqli_num_rows(mysqli_query($this->link, "SELECT `id` FROM `" . $this->settings['comments_table'] . "`"))) |
|
|
|
|
67
|
|
|
$this->install(); |
68
|
|
|
|
69
|
|
|
|
70
|
|
|
// edit comment |
71
|
|
|
if (isset($_POST['comm_edit']) && ($comm = mysqli_query($this->link, "SELECT * FROM `" . $this->settings['comments_table'] . "` |
72
|
|
|
WHERE `id`='" . (int) $_POST['comm_edit'] . "'"))) { |
73
|
|
|
// if the comment exists and the user has the rights to edit it |
74
|
|
|
if (mysqli_num_rows($comm) && $this->hasRights(mysqli_fetch_object($comm))) { |
|
|
|
|
75
|
|
|
$this->grabComment($_SESSION['comm_pageid'], (int) $_POST['comm_edit']); |
76
|
|
|
$this->tmp = "edited"; |
77
|
|
|
} |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
|
81
|
|
|
// delete comment |
82
|
|
|
if (isset($_POST['comm_del'])) |
83
|
|
|
if ($this->delComm($_POST['comm_del'])) |
84
|
|
|
$this->success = "Comment deleted !"; |
85
|
|
|
|
86
|
|
|
// bann ip |
87
|
|
|
if (isset($_GET['comm_ban']) && $this->banIP($_GET['comm_ban'])) // we banned the ip |
88
|
|
|
$this->success = "IP banned !"; |
89
|
|
|
|
90
|
|
|
// UnBann ip |
91
|
|
|
if (isset($_GET['comm_unban']) && $this->unBanIP($_GET['comm_unban'])) |
92
|
|
|
$this->success = "IP UnBanned !"; |
93
|
|
|
|
94
|
|
|
return true; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
|
98
|
|
|
|
99
|
|
|
function grabComment($pageid, $update_id = false) |
|
|
|
|
100
|
|
|
{ |
101
|
|
|
if (session_id() == '') |
102
|
|
|
session_start(); |
103
|
|
|
|
104
|
|
|
$_SESSION['comm_pageid'] = $pageid; |
105
|
|
|
|
106
|
|
|
// we make sure it's a valid post |
107
|
|
|
if ( |
108
|
|
|
isset($_POST['comm_submit']) && isset($_SESSION['comm_token']) && ($_POST['comm_token'] === $_SESSION['comm_token']) && |
109
|
|
|
($this->tmp != 'edited') |
110
|
|
|
) { // we make sure we don't handle the data again if it was an edit |
111
|
|
|
|
112
|
|
|
$name = isset($_POST['comm_name']) ? $_POST['comm_name'] : ''; |
113
|
|
|
$email = isset($_POST['comm_email']) ? $_POST['comm_email'] : ''; |
114
|
|
|
|
115
|
|
|
$min = 2; |
116
|
|
|
|
117
|
|
|
if (!$this->settings['public']) { // if it's not public we use the provided details |
118
|
|
|
// if it's not public and it has $_POST[name] something is wrong |
119
|
|
|
if (isset($_POST['comm_name'])) { |
120
|
|
|
$this->error = "Something is wrong !"; |
121
|
|
|
return false; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
$min = 0; |
125
|
|
|
$name = $this->settings['user_details']['name']; |
126
|
|
|
$email = $this->settings['user_details']['email']; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
if ($this->isBanned($this->ip())) { |
130
|
|
|
$this->error = "You are banned !"; |
131
|
|
|
return false; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
if (!isset($name[$min])) { |
135
|
|
|
$this->error = "Invalid name !"; |
136
|
|
|
return false; |
137
|
|
|
} |
138
|
|
|
$message = $_POST['comm_msg']; |
139
|
|
|
|
140
|
|
|
if (!isset($message[2])) { |
141
|
|
|
$this->error = "Invalid message !"; |
142
|
|
|
return false; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
|
146
|
|
|
// we check in case the email is not valid |
147
|
|
|
if (!$this->settings['optional_email']) |
148
|
|
|
if (!$this->isValidMail($email)) { |
149
|
|
|
$this->error = "Invalid email !"; |
150
|
|
|
return false; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
|
154
|
|
|
// we check if it's an update or a new message |
155
|
|
|
if ($update_id) { |
156
|
|
|
if ($this->settings['public']) |
157
|
|
|
$upd_fields = ",`name` = '" . mysqli_real_escape_string($this->link, $name) . "', |
|
|
|
|
158
|
|
|
`email` = '" . mysqli_real_escape_string($this->link, $email) . "'"; |
159
|
|
|
else |
160
|
|
|
$upd_fields = ''; |
161
|
|
|
|
162
|
|
|
|
163
|
|
|
if (mysqli_query($this->link, "UPDATE `" . $this->settings['comments_table'] . "` SET |
|
|
|
|
164
|
|
|
`message` = '" . mysqli_real_escape_string($this->link, $message) . "' |
165
|
|
|
$upd_fields |
166
|
|
|
WHERE `id` = '" . (int) $update_id . "'")) { |
167
|
|
|
|
168
|
|
|
$this->success = "Comment edited successfully !"; |
169
|
|
|
return true; |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
|
174
|
|
|
// we check if this is a valid reply |
175
|
|
|
if ( |
176
|
|
|
isset($_POST['comm_reply']) && |
177
|
|
|
mysqli_num_rows(mysqli_query($this->link, "SELECT `id` FROM `" . $this->settings['comments_table'] . "` |
|
|
|
|
178
|
|
|
WHERE `id`= '" . (int) $_POST['comm_reply'] . "' AND `parent` = '0'")) |
179
|
|
|
) |
180
|
|
|
$reply = ",`parent` = '" . (int) $_POST['comm_reply'] . "'"; |
181
|
|
|
else |
182
|
|
|
$reply = ''; |
183
|
|
|
|
184
|
|
|
|
185
|
|
|
|
186
|
|
|
if (mysqli_query($this->link, "INSERT INTO `" . $this->settings['comments_table'] . "` SET |
187
|
|
|
`name` = '" . mysqli_real_escape_string($this->link, $name) . "', |
188
|
|
|
`message` = '" . mysqli_real_escape_string($this->link, $message) . "', |
189
|
|
|
`time` = '" . time() . "', |
190
|
|
|
`ip` = '" . mysqli_real_escape_string($this->link, $this->ip()) . "', |
191
|
|
|
`email` = '" . mysqli_real_escape_string($this->link, $email) . "', |
192
|
|
|
`browser` = '" . mysqli_real_escape_string($this->link, $_SERVER['HTTP_USER_AGENT']) . "', |
193
|
|
|
`pageid` = '" . mysqli_real_escape_string($this->link, $pageid) . "', |
194
|
|
|
`isadmin` = '" . (int) $this->settings['isAdmin'] . "' |
195
|
|
|
$reply |
196
|
|
|
")) { |
197
|
|
|
$_SESSION['comm_last_id'] = mysqli_insert_id($this->link); |
|
|
|
|
198
|
|
|
$this->success = "Comment posted successfully !"; |
199
|
|
|
return true; |
200
|
|
|
} else { |
201
|
|
|
$this->error = "Some error camed up !"; |
202
|
|
|
return false; |
203
|
|
|
} |
204
|
|
|
} else if (isset($_POST['comm_submit']) && isset($_SESSION['comm_token']) && ($this->tmp != 'edited')) { |
205
|
|
|
unset($_SESSION['comm_token']); |
206
|
|
|
$this->error = "Invalid request !"; |
207
|
|
|
} |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Lists the comments for the inserted page id |
212
|
|
|
* @param integer $pageid |
213
|
|
|
* @param integer $perpage |
214
|
|
|
* @return string the generated html code |
215
|
|
|
*/ |
216
|
|
|
function generateComments($pageid = 0, $perpage = 10) |
|
|
|
|
217
|
|
|
{ |
218
|
|
|
|
219
|
|
|
if (session_id() == '') |
220
|
|
|
session_start(); |
221
|
|
|
|
222
|
|
|
$_SESSION['comm_pageid'] = $pageid; |
223
|
|
|
|
224
|
|
|
$html = ""; |
225
|
|
|
|
226
|
|
|
|
227
|
|
|
$comments = $this->getComments($pageid, $perpage); |
228
|
|
|
|
229
|
|
|
|
230
|
|
|
// we generate the output of the comments |
231
|
|
|
if ($comments) { |
232
|
|
|
foreach ($comments as $comment) { |
233
|
|
|
if (!($name = $this->getUsername($comment->name))) |
234
|
|
|
$name = $comment->name; |
235
|
|
|
|
236
|
|
|
// show reply link or form |
237
|
|
|
if (isset($_GET['comm_reply']) && ($comment->id == $_GET['comm_reply'])) { |
238
|
|
|
$show_reply = $this->generateForm("?" . $this->queryString('', $this->ignore), 1); |
239
|
|
|
} else { |
240
|
|
|
$show_reply = "<a href='?" . $this->queryString('', $this->ignore) . "&comm_reply=$comment->id#$comment->id'>Reply</a>"; |
241
|
|
|
} |
242
|
|
|
// show normal username or with adminStyles |
243
|
|
|
$style = ""; |
244
|
|
|
if ($comment->isadmin) { |
245
|
|
|
$show_name = "<span style='" . $this->settings['adminStyle']['username'] . "'>" . $this->html($name) . "</span>"; |
246
|
|
|
$style = $this->settings['adminStyle']['box']; |
247
|
|
|
} else { |
248
|
|
|
$show_name = $this->html($name); |
249
|
|
|
} |
250
|
|
|
// show extra info only to admin |
251
|
|
|
$show_extra = ""; |
252
|
|
|
if ($this->settings['isAdmin']) { |
253
|
|
|
$browser = explode(" ", $comment->browser); |
254
|
|
|
$show_extra = "($comment->email | " . $browser[0] . " | $comment->ip)"; |
255
|
|
|
} |
256
|
|
|
$is_del = (isset($_GET['comm_del']) && ($_GET['comm_del'] === $comment->id) && $this->hasRights($comment)) |
257
|
|
|
? " background-color: #FFDE89; border: 1px solid red;" : null; |
258
|
|
|
|
259
|
|
|
$html .= " |
260
|
|
|
<div class='card' id='$comment->id' style='" . $style . $is_del . "'> |
261
|
|
|
<div class='card-body'>"; |
262
|
|
|
|
263
|
|
|
if (isset($_GET['comm_edit']) && ($_GET['comm_edit'] === $comment->id) && $this->hasRights($comment)) { |
264
|
|
|
// we generate the form in edit mode with precompleted data |
265
|
|
|
$html .= $this->generateForm('', 2, $comment); |
266
|
|
|
} else { |
267
|
|
|
$html .= "<a class='float-left mr-2' rel='nofollow, noopener' href='http://gravatar.com'> |
268
|
|
|
<img class='img-thumbnail' src='http://gravatar.com/avatar/" . md5($comment->email) . "'> |
269
|
|
|
</a>"; |
270
|
|
|
$html .= "<h5 class='card-title'> |
271
|
|
|
$show_name $show_extra |
272
|
|
|
<small class='text-muted'>" . $this->tsince($comment->time) . "</small> |
273
|
|
|
" . $this->admin_options($comment) . " |
274
|
|
|
</h5> |
275
|
|
|
<p>" . nl2br($this->html($comment->message)) . "</p>"; |
276
|
|
|
} |
277
|
|
|
if ($is_del) { |
278
|
|
|
$html .= $this->gennerateConfirm('', 'comm_del', $comment->id); |
279
|
|
|
} else { |
280
|
|
|
$html .= $show_reply; |
281
|
|
|
} |
282
|
|
|
$html .= $this->generateReplies($comment->id) . " |
283
|
|
|
</div> |
284
|
|
|
</div>"; |
285
|
|
|
} |
286
|
|
|
} |
287
|
|
|
$html .= $this->generatePages($pageid, $perpage); |
288
|
|
|
|
289
|
|
|
return $html; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
|
293
|
|
|
function generateReplies($comm_id, $limit = 3) |
|
|
|
|
294
|
|
|
{ |
295
|
|
|
$html = ""; |
296
|
|
|
$comments = $this->getReplies($comm_id, $limit); |
297
|
|
|
// we generate the output of the comments |
298
|
|
|
if ($comments) |
299
|
|
|
foreach ($comments as $comment) { |
300
|
|
|
if (!($name = $this->getUsername($comment->name))) |
301
|
|
|
$name = $comment->name; |
302
|
|
|
|
303
|
|
|
// show normal username or with adminStyles |
304
|
|
|
$style = ""; |
305
|
|
|
if ($comment->isadmin) { |
306
|
|
|
$show_name = "<span style='" . $this->settings['adminStyle']['username'] . "'>" . $this->html($name) . "</span>"; |
307
|
|
|
$style = $this->settings['adminStyle']['box']; |
308
|
|
|
} else |
309
|
|
|
$show_name = $this->html($name); |
310
|
|
|
|
311
|
|
|
// show extra info only to admin |
312
|
|
|
$show_extra = ""; |
313
|
|
|
if ($this->settings['isAdmin']) { |
314
|
|
|
$browser = explode(" ", $comment->browser); |
315
|
|
|
$show_extra = "($comment->email | " . $browser[0] . " | $comment->ip)"; |
316
|
|
|
} |
317
|
|
|
$is_del = (isset($_GET['comm_del']) && ($_GET['comm_del'] === $comment->id) && $this->hasRights($comment)) |
318
|
|
|
? " background-color: #FFDE89; border: 1px solid red;" : null; |
319
|
|
|
|
320
|
|
|
$html .= " |
321
|
|
|
<div class='media' id='$comment->id' style='" . $style . $is_del . "'> |
322
|
|
|
<a class='pull-left' href='http://gravatar.com'> |
323
|
|
|
<img class='media-object' src='http://gravatar.com/avatar/" . md5($comment->email) . "'> |
324
|
|
|
</a> |
325
|
|
|
<div class='media-body'>"; |
326
|
|
|
|
327
|
|
|
|
328
|
|
|
if (isset($_GET['comm_edit']) && ($_GET['comm_edit'] === $comment->id) && $this->hasRights($comment)) |
329
|
|
|
// we generate the form in edit mode with precompleted data |
330
|
|
|
$html .= $this->generateForm('', 2, $comment); |
331
|
|
|
else |
332
|
|
|
$html .= "<h4 class='media-heading'> |
333
|
|
|
$show_name $show_extra |
334
|
|
|
<small class='muted'>" . $this->tsince($comment->time) . " replied </small> |
335
|
|
|
" . $this->admin_options($comment) . " |
336
|
|
|
</h4> |
337
|
|
|
<p>" . nl2br($this->html($comment->message)) . "</p>"; |
338
|
|
|
|
339
|
|
|
if ($is_del) |
340
|
|
|
$html .= $this->gennerateConfirm('', 'comm_del', $comment->id); |
341
|
|
|
|
342
|
|
|
$html .= "</div></div>"; |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
return $html; |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
function generateForm($location = '', $type = 0, $comment = false) |
|
|
|
|
349
|
|
|
{ |
350
|
|
|
$this->setToken(); |
351
|
|
|
if ($location == '') |
352
|
|
|
$location = "?" . $this->queryString('', $this->ignore); |
353
|
|
|
|
354
|
|
|
|
355
|
|
|
if (!$comment) |
356
|
|
|
$comment = (object) array("name" => "", "email" => "", "message" => ""); |
357
|
|
|
|
358
|
|
|
if ($type == 1) |
359
|
|
|
$title = "<input type='hidden' name='comm_reply' value='" . (int) $_GET['comm_reply'] . "'>Post a reply"; |
360
|
|
|
else if ($type == 2) |
361
|
|
|
$title = "<input type='hidden' name='comm_edit' value='" . (int) $_GET['comm_edit'] . "'>Edit comment"; |
362
|
|
|
else |
363
|
|
|
$title = "Post a comment"; |
364
|
|
|
|
365
|
|
|
$show_name_email = ''; |
366
|
|
|
|
367
|
|
|
if ($this->settings['public']) { |
368
|
|
|
$show_name_email = "<div class='control-group'> |
369
|
|
|
<label class='control-label' for='comm_name'>Name</label> |
370
|
|
|
<div class='controls'> |
371
|
|
|
<input id='comm_name' name='comm_name' type='text' class='input-xlarge' value='$comment->name'> |
372
|
|
|
|
373
|
|
|
</div> |
374
|
|
|
</div> |
375
|
|
|
|
376
|
|
|
<div class='control-group'> |
377
|
|
|
<label class='control-label' for='comm_email'>Email</label> |
378
|
|
|
<div class='controls'> |
379
|
|
|
<input id='comm_email' name='comm_email' type='text' class='input-xlarge' value='$comment->email'> |
380
|
|
|
<p> |
381
|
|
|
" . ($this->settings['optional_email'] ? "(optional, it will not be public.)" : "") . " |
382
|
|
|
</p> |
383
|
|
|
</div> |
384
|
|
|
</div>"; |
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
|
388
|
|
|
$html = " |
389
|
|
|
<form class='form-horizontal' action='$location#comm_status' method='post'> |
390
|
|
|
<fieldset> |
391
|
|
|
<legend>$title</legend> |
392
|
|
|
|
393
|
|
|
$show_name_email |
394
|
|
|
|
395
|
|
|
<div class='md-form mb-2'> |
396
|
|
|
<label class='control-label' for='comm_msg'>Message</label> |
397
|
|
|
<div class='controls'> |
398
|
|
|
<textarea class='form-control' id='comm_msg' name='comm_msg'>$comment->message</textarea> |
399
|
|
|
</div> |
400
|
|
|
</div> |
401
|
|
|
|
402
|
|
|
<input type='hidden' name='comm_token' value='" . $_SESSION['comm_token'] . "'> |
403
|
|
|
|
404
|
|
|
<div class='md-form mb-2'> |
405
|
|
|
<div class='controls'> |
406
|
|
|
<input type='submit' id='comm_submit' name='comm_submit' class='btn btn-primary' value='Post'> |
407
|
|
|
" . ($type ? "<input type='submit' id='comm_cancel' value='Cancel' class='btn'>" : "") . " |
408
|
|
|
</div> |
409
|
|
|
</div> |
410
|
|
|
|
411
|
|
|
</fieldset> |
412
|
|
|
</form>"; |
413
|
|
|
|
414
|
|
|
return $html; |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* it will create the table to hold the comments |
419
|
|
|
* @return boolean true if the install succeeds |
420
|
|
|
*/ |
421
|
|
|
function install() |
|
|
|
|
422
|
|
|
{ |
423
|
|
|
|
424
|
|
|
$sql = "CREATE TABLE IF NOT EXISTS `" . $this->settings['comments_table'] . "` ( |
425
|
|
|
`id` int(11) NOT NULL AUTO_INCREMENT, |
426
|
|
|
`name` varchar(255) NOT NULL, |
427
|
|
|
`message` text NOT NULL, |
428
|
|
|
`time` int(11) NOT NULL, |
429
|
|
|
`ip` varchar(255) NOT NULL, |
430
|
|
|
`email` varchar(255) NOT NULL, |
431
|
|
|
`browser` varchar(255) NOT NULL, |
432
|
|
|
`pageid` int(11) NOT NULL, |
433
|
|
|
`parent` int(11) NOT NULL, |
434
|
|
|
`isadmin` int(11) NOT NULL, |
435
|
|
|
PRIMARY KEY (`id`) |
436
|
|
|
);"; |
437
|
|
|
|
438
|
|
|
$sql2 = "CREATE TABLE IF NOT EXISTS `_banned` ( |
439
|
|
|
`ip` varchar(255) NOT NULL, |
440
|
|
|
UNIQUE KEY `ip` (`ip`) |
441
|
|
|
);"; |
442
|
|
|
|
443
|
|
|
if (mysqli_query($this->link, $sql) && mysqli_query($this->link, $sql2)) |
|
|
|
|
444
|
|
|
return true; |
445
|
|
|
|
446
|
|
|
return false; |
447
|
|
|
} |
448
|
|
|
/** |
449
|
|
|
* gets the comments from the db |
450
|
|
|
* @param integer $pageid the id for the specific page |
451
|
|
|
* @param integer $perpage number of comments perpage |
452
|
|
|
* @return array the comments |
453
|
|
|
*/ |
454
|
|
|
function getComments($pageid = 0, $perpage = 10) |
|
|
|
|
455
|
|
|
{ |
456
|
|
|
$comments = array(); |
457
|
|
|
|
458
|
|
|
$sql = "SELECT * FROM `" . $this->settings['comments_table'] . "` WHERE `parent` = 0 "; |
459
|
|
|
|
460
|
|
|
if ($pageid) |
461
|
|
|
$sql .= "AND `pageid` = '" . mysqli_real_escape_string($this->link, $pageid) . "'"; |
|
|
|
|
462
|
|
|
|
463
|
|
|
// some sorting options |
464
|
|
|
$sql .= " " . $this->settings['sort'] . " "; // this is pasted as is |
465
|
|
|
|
466
|
|
|
|
467
|
|
|
// grab the page number |
468
|
|
|
$page_number = !isset($_GET['comm_page']) || ((int) $_GET['comm_page'] <= 0) ? 1 : (int) $_GET['comm_page']; |
469
|
|
|
|
470
|
|
|
$total_results = mysqli_num_rows(mysqli_query($this->link, $sql)); |
|
|
|
|
471
|
|
|
|
472
|
|
|
if ($page_number > ceil($total_results / $perpage)) |
473
|
|
|
$page_number = ceil($total_results / $perpage); |
474
|
|
|
|
475
|
|
|
$start = ($page_number - 1) * $perpage; |
476
|
|
|
|
477
|
|
|
$sql .= "LIMIT $start, $perpage"; |
478
|
|
|
|
479
|
|
|
if ($result = mysqli_query($this->link, $sql)) |
480
|
|
|
while ($row = mysqli_fetch_object($result)) |
|
|
|
|
481
|
|
|
$comments[] = $row; |
482
|
|
|
else |
483
|
|
|
return false; |
|
|
|
|
484
|
|
|
|
485
|
|
|
return $comments; |
486
|
|
|
} |
487
|
|
|
/** |
488
|
|
|
* gets the replies to a certain comment |
489
|
|
|
* @param integer $comm_id the id for the specific comment |
490
|
|
|
* @param integer $limit max number of comments to be displayed as reply |
491
|
|
|
* @return array the comments |
492
|
|
|
*/ |
493
|
|
|
function getReplies($comm_id = 0, $limit = 3) |
|
|
|
|
494
|
|
|
{ |
495
|
|
|
$comments = array(); |
496
|
|
|
|
497
|
|
|
$sql = "SELECT * FROM `" . $this->settings['comments_table'] . "` |
498
|
|
|
WHERE `parent` = '" . mysqli_real_escape_string($this->link, $comm_id) . "'"; |
|
|
|
|
499
|
|
|
|
500
|
|
|
// limitation |
501
|
|
|
$sql .= "LIMIT 0, $limit"; |
502
|
|
|
|
503
|
|
|
if ($result = mysqli_query($this->link, $sql)) |
|
|
|
|
504
|
|
|
while ($row = mysqli_fetch_object($result)) |
|
|
|
|
505
|
|
|
$comments[] = $row; |
506
|
|
|
else |
507
|
|
|
return false; |
|
|
|
|
508
|
|
|
|
509
|
|
|
return $comments; |
510
|
|
|
} |
511
|
|
|
|
512
|
|
|
/** |
513
|
|
|
* it parses the text for output |
514
|
|
|
* @param string $text the text to be parsed |
515
|
|
|
* @return string paesed text |
516
|
|
|
*/ |
517
|
|
|
function html($text) |
|
|
|
|
518
|
|
|
{ |
519
|
|
|
return htmlentities($text, ENT_QUOTES); |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
/** |
523
|
|
|
* while developing this class a small problem camed up, |
524
|
|
|
* what if i have a user system already and i want to store the userid instread of he's username(in case he changes it) ? |
525
|
|
|
* for this matter i made this function which by default will return false |
526
|
|
|
* which means that we will consider that the `name` column is a string not an integer(userid) |
527
|
|
|
* BUT if you store the userid in the name column you have to make sure that this function |
528
|
|
|
* will return the username coresponding to that id, i included an example |
529
|
|
|
* |
530
|
|
|
*/ |
531
|
|
|
function getUsername($userid) |
|
|
|
|
532
|
|
|
{ |
533
|
|
|
return false; |
534
|
|
|
// in case you decide to store the userid use this |
535
|
|
|
// $user = mysqli_fetch_object(mysql_query($this->link, "SELECT * FROM `users` WHERE 'userid' = '".(int)$userid."'")); |
536
|
|
|
// return $user->username; |
537
|
|
|
} |
538
|
|
|
|
539
|
|
|
/** |
540
|
|
|
* Time elapes since a times |
541
|
|
|
* @param int $time The past time |
542
|
|
|
* @return string time elapssed |
543
|
|
|
* credits: http://stackoverflow.com/a/2916189/1579481 |
544
|
|
|
*/ |
545
|
|
|
function tsince($time, $end_msg = 'ago') |
|
|
|
|
546
|
|
|
{ |
547
|
|
|
|
548
|
|
|
$time = abs(time() - $time); // to get the time since that moment |
549
|
|
|
|
550
|
|
|
if ($time == 0) |
551
|
|
|
return "Just now"; |
552
|
|
|
|
553
|
|
|
$tokens = array( |
554
|
|
|
31536000 => 'year', |
555
|
|
|
2592000 => 'month', |
556
|
|
|
604800 => 'week', |
557
|
|
|
86400 => 'day', |
558
|
|
|
3600 => 'hour', |
559
|
|
|
60 => 'minute', |
560
|
|
|
1 => 'second' |
561
|
|
|
); |
562
|
|
|
|
563
|
|
|
foreach ($tokens as $unit => $text) { |
564
|
|
|
if ($time < $unit) continue; |
565
|
|
|
$numberOfUnits = floor($time / $unit); |
566
|
|
|
return $numberOfUnits . ' ' . $text . (($numberOfUnits > 1) ? 's' : '') . ' ' . $end_msg; |
567
|
|
|
} |
568
|
|
|
} |
569
|
|
|
|
570
|
|
|
function isValidMail($mail) |
|
|
|
|
571
|
|
|
{ |
572
|
|
|
|
573
|
|
|
if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) |
574
|
|
|
return FALSE; |
575
|
|
|
|
576
|
|
|
|
577
|
|
|
list($username, $maildomain) = explode("@", $mail); |
578
|
|
|
if (checkdnsrr($maildomain, "MX")) |
579
|
|
|
return TRUE; |
580
|
|
|
|
581
|
|
|
return FALSE; |
582
|
|
|
} |
583
|
|
|
|
584
|
|
|
// Returns the real IP address of the user |
585
|
|
|
function ip() |
|
|
|
|
586
|
|
|
{ |
587
|
|
|
// No IP found (will be overwritten by for |
588
|
|
|
// if any IP is found behind a firewall) |
589
|
|
|
$ip = FALSE; |
590
|
|
|
|
591
|
|
|
// If HTTP_CLIENT_IP is set, then give it priority |
592
|
|
|
if (!empty($_SERVER["HTTP_CLIENT_IP"])) { |
593
|
|
|
$ip = $_SERVER["HTTP_CLIENT_IP"]; |
594
|
|
|
} |
595
|
|
|
|
596
|
|
|
// User is behind a proxy and check that we discard RFC1918 IP addresses |
597
|
|
|
// if they are behind a proxy then only figure out which IP belongs to the |
598
|
|
|
// user. Might not need any more hackin if there is a squid reverse proxy |
599
|
|
|
// infront of apache. |
600
|
|
|
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { |
601
|
|
|
|
602
|
|
|
// Put the IP's into an array which we shall work with shortly. |
603
|
|
|
$ips = explode(", ", $_SERVER['HTTP_X_FORWARDED_FOR']); |
604
|
|
|
if ($ip) { |
605
|
|
|
array_unshift($ips, $ip); |
606
|
|
|
$ip = FALSE; |
607
|
|
|
} |
608
|
|
|
|
609
|
|
|
for ($i = 0; $i < count($ips); $i++) { |
|
|
|
|
610
|
|
|
// Skip RFC 1918 IP's 10.0.0.0/8, 172.16.0.0/12 and |
611
|
|
|
// 192.168.0.0/16 |
612
|
|
|
if (!preg_match('/^(?:10|172\.(?:1[6-9]|2\d|3[01])|192\.168)\./', $ips[$i])) { |
613
|
|
|
if (version_compare(phpversion(), "5.0.0", ">=")) { |
614
|
|
|
if (ip2long($ips[$i]) != false) { |
|
|
|
|
615
|
|
|
$ip = $ips[$i]; |
616
|
|
|
break; |
617
|
|
|
} |
618
|
|
|
} else { |
619
|
|
|
if (ip2long($ips[$i]) != -1) { |
620
|
|
|
$ip = $ips[$i]; |
621
|
|
|
break; |
622
|
|
|
} |
623
|
|
|
} |
624
|
|
|
} |
625
|
|
|
} |
626
|
|
|
} |
627
|
|
|
|
628
|
|
|
// Return with the found IP or the remote address |
629
|
|
|
return ($ip ? $ip : $_SERVER['REMOTE_ADDR']); |
630
|
|
|
} |
631
|
|
|
/** |
632
|
|
|
* sets a random token stored in the session used to validate the form submit |
633
|
|
|
*/ |
634
|
|
|
function setToken() |
|
|
|
|
635
|
|
|
{ |
636
|
|
|
if (session_id() == '') |
637
|
|
|
session_start(); |
638
|
|
|
|
639
|
|
|
$_SESSION['comm_token'] = md5(time() . rand()); |
640
|
|
|
} |
641
|
|
|
/** |
642
|
|
|
* it will return the query string as hidden fields or as url |
643
|
|
|
* @param string $type type of output |
644
|
|
|
* @param array $ignore ignored elements |
645
|
|
|
* @return string |
646
|
|
|
*/ |
647
|
|
|
function queryString($type = '', $ignore = array()) |
|
|
|
|
648
|
|
|
{ |
649
|
|
|
|
650
|
|
|
$result = ''; |
651
|
|
|
|
652
|
|
|
foreach ($_GET as $k => $v) { |
653
|
|
|
if ((is_array($ignore) && in_array($k, $ignore)) |
654
|
|
|
|| (is_string($ignore) && preg_match($ignore, $k)) |
655
|
|
|
) |
656
|
|
|
continue; |
657
|
|
|
|
658
|
|
|
if ($type == 'hidden') { |
659
|
|
|
$result .= "<input type='hidden' name='" . urlencode($k) . "' value='" . urlencode($v) . "'>"; |
660
|
|
|
} else { |
661
|
|
|
$result[] = urlencode($k) . "=" . urlencode($v); |
662
|
|
|
} |
663
|
|
|
} |
664
|
|
|
|
665
|
|
|
if (is_array($result)) |
|
|
|
|
666
|
|
|
return implode("&", $result); |
667
|
|
|
|
668
|
|
|
return $result; |
669
|
|
|
} |
670
|
|
|
|
671
|
|
|
|
672
|
|
|
/** |
673
|
|
|
* generates a confirmation form |
674
|
|
|
* @return string the html code of the form |
675
|
|
|
*/ |
676
|
|
|
function gennerateConfirm($location = '', $info_name = 'comm_del', $info_value = 0, $submit = "I'm sure, Delete") |
|
|
|
|
677
|
|
|
{ |
678
|
|
|
|
679
|
|
|
if ($location == '') |
680
|
|
|
$location = "?" . $this->queryString('', $this->ignore); |
681
|
|
|
|
682
|
|
|
return "<form class='form-horizontal' action='$location' method='post'> |
683
|
|
|
<div class='control-group'> |
684
|
|
|
<div class='controls'> |
685
|
|
|
" . ($info_name ? "<input type='hidden' name='$info_name' value='$info_value'>" : "") . " |
686
|
|
|
<input type='submit' id='comm_submit' name='comm_confirm' class='btn btn-primary' value='$submit'> |
687
|
|
|
<a href='" . $_SERVER['HTTP_REFERER'] . "' class='btn'>Cancel</a> |
688
|
|
|
</div> |
689
|
|
|
</div> |
690
|
|
|
</form>"; |
691
|
|
|
} |
692
|
|
|
/** |
693
|
|
|
* checks if the current user has the rights to delete/edit a comment |
694
|
|
|
* @param object $comment data related to one comment |
695
|
|
|
* @return boolean [description] |
696
|
|
|
*/ |
697
|
|
|
function hasRights($comment) |
|
|
|
|
698
|
|
|
{ |
699
|
|
|
if (session_id() == '') |
700
|
|
|
session_start(); |
701
|
|
|
|
702
|
|
|
if ($this->settings['isAdmin'] || (isset($_SESSION['comm_last_id']) && $_SESSION['comm_last_id'] == $comment->id)) |
703
|
|
|
return true; |
704
|
|
|
return false; |
705
|
|
|
} |
706
|
|
|
/** |
707
|
|
|
* returns the html code of the options available |
708
|
|
|
* @param object $comment data related to one comment |
709
|
|
|
* @return string the html code to display the options |
710
|
|
|
*/ |
711
|
|
|
function admin_options($comment) |
|
|
|
|
712
|
|
|
{ |
713
|
|
|
// if is admin or the person who posted the message |
714
|
|
|
if ($this->hasRights($comment)) |
715
|
|
|
return "<a href='?" . $this->queryString('', $this->ignore) . "&comm_edit=$comment->id#$comment->id'>Edit</a> |
716
|
|
|
| <a href='?" . $this->queryString('', $this->ignore) . "&comm_del=$comment->id#$comment->id'>Delete</a>" . |
717
|
|
|
($this->settings['isAdmin'] ? //if is admin |
718
|
|
|
" | <a href='?" . $this->queryString('', $this->ignore) . "&comm_" . |
719
|
|
|
($this->isBanned($comment->ip) ? "un" : "") . "ban=" . urlencode($comment->ip) . "'>" . |
720
|
|
|
($this->isBanned($comment->ip) ? "Un" : "") . "Ban</a>" : ""); |
721
|
|
|
} |
722
|
|
|
|
723
|
|
|
|
724
|
|
|
/** |
725
|
|
|
* will generate the html code for page numbers |
726
|
|
|
* @param interger $total the total number of elements |
|
|
|
|
727
|
|
|
* @param interger $page current page |
728
|
|
|
* @param integer $perpage number of elements per page |
729
|
|
|
* @return string the generated html code |
730
|
|
|
*/ |
731
|
|
|
function generatePages($pageid, $perpage = 10) |
|
|
|
|
732
|
|
|
{ |
733
|
|
|
|
734
|
|
|
|
735
|
|
|
$sql = "SELECT `id` FROM `" . $this->settings['comments_table'] . "` WHERE `parent` = 0 "; |
736
|
|
|
|
737
|
|
|
if ($pageid) |
738
|
|
|
$sql .= " AND `pageid`='" . (int) $pageid . "'"; |
739
|
|
|
|
740
|
|
|
|
741
|
|
|
$total = mysqli_num_rows(mysqli_query($this->link, $sql)); |
|
|
|
|
742
|
|
|
|
743
|
|
|
$total_pages = ceil($total / $perpage); |
744
|
|
|
|
745
|
|
|
$page = !isset($_GET['comm_page']) || ((int) $_GET['comm_page'] <= 0) ? 1 : (int) $_GET['comm_page']; |
746
|
|
|
|
747
|
|
|
$query = "&" . $this->queryString('', array('comm_page')); |
748
|
|
|
|
749
|
|
|
$html = "<div class='pagination'><ul>"; |
750
|
|
|
|
751
|
|
|
if ($page > 4) |
752
|
|
|
$html .= "<li><a href='?$query'>First</a></li>"; |
753
|
|
|
|
754
|
|
|
if ($page > 1) |
755
|
|
|
$html .= "<li><a href='?comm_page=" . ($page - 1) . "$query'>Prev</a> </li>"; |
756
|
|
|
|
757
|
|
|
for ($i = max(1, $page - 3); $i <= min($page + 3, $total_pages); $i++) |
758
|
|
|
$html .= ($i == $page ? "<li class='active'><a>" . $i . "</a></li>" : " <li><a href='?comm_page=$i$query'>$i</a></li> "); |
759
|
|
|
|
760
|
|
|
if ($page < $total_pages) |
761
|
|
|
$html .= "<li><a href='?comm_page=" . ($page + 1) . "$query'>Next</a></li>"; |
762
|
|
|
|
763
|
|
|
if ($page < $total_pages - 3) |
764
|
|
|
$html .= "<li><a href='?comm_page=$total_pages$query'> Last </a></li>"; |
765
|
|
|
|
766
|
|
|
$html .= "</ul></div>"; |
767
|
|
|
|
768
|
|
|
return $html; |
769
|
|
|
} |
770
|
|
|
|
771
|
|
|
/** |
772
|
|
|
* deletes comment based on the comment id, it also checks for the rights of the user. |
773
|
|
|
* @param interger $comment_id the id of the comment to be deleted |
774
|
|
|
* @return boolean true on success |
775
|
|
|
*/ |
776
|
|
|
function delComm($comment_id) |
|
|
|
|
777
|
|
|
{ |
778
|
|
|
$comm = mysqli_query($this->link, "SELECT `id` FROM `" . $this->settings['comments_table'] . "` WHERE `id` = '" . (int) $comment_id . "'"); |
|
|
|
|
779
|
|
|
if (mysqli_num_rows($comm) && $this->hasRights(mysqli_fetch_object($comm))) { |
|
|
|
|
780
|
|
|
mysqli_query($this->link, "DELETE FROM `" . $this->settings['comments_table'] . "` |
781
|
|
|
WHERE `id` = '" . (int) $comment_id . "' OR `parent` = '" . (int) $comment_id . "'"); |
782
|
|
|
|
783
|
|
|
return true; |
784
|
|
|
} |
785
|
|
|
|
786
|
|
|
return false; |
787
|
|
|
} |
788
|
|
|
/** |
789
|
|
|
* Adds the inserted ip in the banned list |
790
|
|
|
* @param string $ip the ip to be banned |
791
|
|
|
*/ |
792
|
|
|
function banIP($ip) |
|
|
|
|
793
|
|
|
{ |
794
|
|
|
if ($this->settings['isAdmin']) |
795
|
|
|
if (mysqli_query($this->link, "INSERT INTO `" . $this->settings['banned_table'] . "` |
|
|
|
|
796
|
|
|
SET `ip` = '" . mysqli_real_escape_string($this->link, $ip) . "'")) |
|
|
|
|
797
|
|
|
return true; |
798
|
|
|
return false; |
799
|
|
|
} |
800
|
|
|
|
801
|
|
|
/** |
802
|
|
|
* Deletes an ip from the banned list. |
803
|
|
|
* @param string $ip the ip to be unbanned |
804
|
|
|
*/ |
805
|
|
|
function unBanIP($ip) |
|
|
|
|
806
|
|
|
{ |
807
|
|
|
if ($this->settings['isAdmin']) { |
808
|
|
|
mysqli_query($this->link, "DELETE FROM `" . $this->settings['banned_table'] . "` |
|
|
|
|
809
|
|
|
WHERE `ip` = '" . mysqli_real_escape_string($this->link, $ip) . "'"); |
|
|
|
|
810
|
|
|
return true; |
811
|
|
|
} |
812
|
|
|
|
813
|
|
|
return false; |
814
|
|
|
} |
815
|
|
|
/** |
816
|
|
|
* checks if an ip is banned |
817
|
|
|
* @param string $ip ip to be checked |
818
|
|
|
* @return boolean true if the ip is banned |
819
|
|
|
*/ |
820
|
|
|
function isBanned($ip) |
|
|
|
|
821
|
|
|
{ |
822
|
|
|
// no need to check the same ip 2 times in a row |
823
|
|
|
if (count($this->checked_ips) && in_array($ip, array_keys($this->checked_ips))) |
824
|
|
|
return $this->checked_ips[$ip]; |
825
|
|
|
|
826
|
|
|
$this->checked_ips[$ip] = $ip; |
827
|
|
|
|
828
|
|
|
|
829
|
|
|
if (mysqli_num_rows(mysqli_query($this->link, "SELECT * FROM `" . $this->settings['banned_table'] . "` |
|
|
|
|
830
|
|
|
WHERE `ip` = '" . mysqli_real_escape_string($this->link, $ip) . "'"))) { |
|
|
|
|
831
|
|
|
$this->checked_ips[$ip] = true; |
832
|
|
|
return true; |
833
|
|
|
} |
834
|
|
|
$this->checked_ips[$ip] = false; |
835
|
|
|
|
836
|
|
|
|
837
|
|
|
return false; |
838
|
|
|
} |
839
|
|
|
} |
840
|
|
|
|
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.