Subversion Repositories php_guestbook

Compare Revisions

No changes between revisions

Regard whitespace Rev 3 → Rev 4

/trunk/README.md
0,0 → 1,12
 
# PHP Gästebuch (PHP Guestbook, currently only in German)
 
Ein Gästebuch, entwickelt mit PHP und MySQL.
Unterstützt werden unter Anderem:
- Freischaltung von Einträgen via e-Mail
- Absicherung vor Spam mittels ReCaptcha
- Smileys
[Beispiel 1](https://www.reptile-universum.de/guestbook/)
[Beispiel 2](https://www.daniel-marschall.de/guestbooks/altheidelberg/)
/trunk/_install/install.php
19,9 → 19,9
if (substr($query, 0, 2) == '--') continue;
$query .= ';';
 
mysql_query($query);
db_query($query);
 
$err = mysql_error();
$err = db_error();
if ($err) {
fwrite(STDERR, "mySQL error $err at query $query\n\n");
}
/trunk/_install/upgrade_1.3_to_2.x.php
19,9 → 19,9
if (substr($query, 0, 2) == '--') continue;
$query .= ';';
 
mysql_query($query);
db_query($query);
 
$err = mysql_error();
$err = db_error();
if ($err) {
fwrite(STDERR, "mySQL error $err at query $query\n\n");
}
/trunk/includes/database.inc.php
2,24 → 2,109
 
function verbinden() {
global $mysql_database, $mysql_server, $mysql_pass, $mysql_user;
global $link2;
 
$link2 = mysql_connect($mysql_server, $mysql_user, $mysql_pass);
if (!$link2) {
die('<b>Verbindung zum MySQL-Server konnte nicht hergestellt werden! ('.mysql_error().')</b>');
if (!db_connect($mysql_server, $mysql_user, $mysql_pass)) {
die('<b>Verbindung zum MySQL-Server konnte nicht hergestellt werden! ('.db_error().')</b>');
}
 
if (!mysql_select_db($mysql_database)) {
die('<b>Verbindung zum MySQL-Server konnte nicht hergestellt werden! ('.mysql_error().')</b>');
if (!db_select_db($mysql_database)) {
die('<b>Verbindung zum MySQL-Server konnte nicht hergestellt werden! ('.db_error().')</b>');
}
 
register_shutdown_function('trennen');
mysql_select_db($mysql_database);
db_select_db($mysql_database);
}
 
function trennen() {
global $link2;
@mysql_close($link2);
@db_close();
}
 
?>
// Liefert die Anzahl der Zeilen im Ergebnis
function db_num_rows($result) {
if (!$result) {
$err = db_error();
throw new Exception("Called db_num_rows() with an erroneous argument.".($err == '' ? '' : " Possible cause: $err"));
}
return $result->num_rows;
}
 
// Liefert eine Ergebniszeile als Objekt
function db_fetch_object($result, $class_name="stdClass", $params=null) {
if (!$result) {
$err = db_error();
throw new Exception("Called db_fetch_object() with an erroneous argument.".($err == '' ? '' : " Possible cause: $err"));
}
if ($params) {
return $result->fetch_object($class_name, $params);
} else {
return $result->fetch_object($class_name);
}
}
 
// Öffnet eine Verbindung zu einem MySQL-Server
function db_connect($server=null, $username=null, $password=null, $new_link=false, $client_flags=0) {
global $vts_mysqli;
$ary = explode(':', $server);
$host = $ary[0];
$ini_port = ini_get("mysqli.default_port");
$port = isset($ary[1]) ? (int)$ary[1] : ($ini_port ? (int)$ini_port : 3306);
if (is_null($server)) $port = ini_get("mysqli.default_host");
if (is_null($username)) $port = ini_get("mysqli.default_user");
if (is_null($password)) $port = ini_get("mysqli.default_password");
$vts_mysqli = new mysqli($host, $username, $password, /*dbname*/'', $port, ini_get("mysqli.default_socket"));
return (empty($vts_mysqli->connect_error) && ($vts_mysqli->connect_errno == 0)) ? $vts_mysqli : false;
}
 
// Schließt eine Verbindung zu MySQL
function db_close($link_identifier=NULL) {
global $vts_mysqli;
$li = is_null($link_identifier) ? $vts_mysqli : $link_identifier;
if (is_null($li)) throw new Exception("Cannot execute db_close(). No valid connection to server.");
 
return $li->close();
}
 
// Liefert den Fehlertext der zuvor ausgeführten MySQL Operation
function db_error($link_identifier=NULL) {
global $vts_mysqli;
$li = is_null($link_identifier) ? $vts_mysqli : $link_identifier;
if (is_null($li)) throw new Exception("Cannot execute db_error(). No valid connection to server.");
 
return !empty($li->connect_error) ? $li->connect_error : $li->error;
}
 
// Maskiert spezielle Zeichen innerhalb eines Strings für die Verwendung in einer SQL-Anweisung
function db_real_escape_string($unescaped_string, $link_identifier=NULL) {
global $vts_mysqli;
$li = is_null($link_identifier) ? $vts_mysqli : $link_identifier;
if (is_null($li)) throw new Exception("Cannot execute db_real_escape_string(). No valid connection to server.");
 
return $li->escape_string($unescaped_string);
}
 
// Sendet eine Anfrage an MySQL
function db_query($query, $link_identifier=NULL) {
global $vts_mysqli;
$li = is_null($link_identifier) ? $vts_mysqli : $link_identifier;
if (is_null($li)) throw new Exception("Cannot execute db_query(). No valid connection to server.");
 
return $li->query($query, $resultmode=MYSQLI_STORE_RESULT);
}
 
// Auswahl einer MySQL Datenbank
function db_select_db($database_name, $link_identifier=NULL) {
global $vts_mysqli;
$li = is_null($link_identifier) ? $vts_mysqli : $link_identifier;
if (is_null($li)) throw new Exception("Cannot execute db_select_db(). No valid connection to server.");
 
return $li->select_db($database_name);
}
 
// Liefert die ID, die in der vorherigen Abfrage erzeugt wurde
function db_insert_id($link_identifier=NULL) {
global $vts_mysqli;
$li = is_null($link_identifier) ? $vts_mysqli : $link_identifier;
if (is_null($li)) throw new Exception("Cannot execute db_insert_id(). No valid connection to server.");
 
return $li->insert_id;
}
/trunk/includes/ip_functions.inc.php
2,8 → 2,8
 
/*
* IP functions
* Copyright 2015 Daniel Marschall, ViaThinkSoft
* Version 2015-10-27
* Copyright 2015-2022 Daniel Marschall, ViaThinkSoft
* Version 2021-01-07
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
18,11 → 18,12
* limitations under the License.
*/
 
function get_real_ip() {
// Attention in re $allow_proxy: It is not secure to use these, since they are not validated: http://www.thespanner.co.uk/2007/12/02/faking-the-unexpected/
function get_real_ip($allow_proxy=false) {
/* Eindeutige IP Adresse erhalten, auch bei Proxies und (neu:) von SSH connections im CLI modus */
// http://lists.phpbar.de/pipermail/php/Week-of-Mon-20040322/007749.html
// Modificated by VTS
// Version: 2015-10-27
// Version: 2021-01-07
 
// TODO: ipv6
 
29,12 → 30,8
if (isset($_SERVER['SSH_CLIENT'])) { $ary = explode(' ', $_SERVER['SSH_CLIENT']); return $ary[0]; }
if (isset($_SERVER['SSH_CONNECTION'])) { $ary = explode(' ', $_SERVER['SSH_CONNECTION']); return $ary[0]; }
 
$client_ip = (isset($_SERVER['HTTP_CLIENT_IP'])) ? $_SERVER['HTTP_CLIENT_IP'] : '';
 
// It is not secure to use these, since they are not validated: http://www.thespanner.co.uk/2007/12/02/faking-the-unexpected/
// $x_forwarded_for = (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '';
$x_forwarded_for = '';
 
$client_ip = ($allow_proxy && isset($_SERVER['HTTP_CLIENT_IP'])) ? $_SERVER['HTTP_CLIENT_IP'] : '';
$x_forwarded_for = ($allow_proxy && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '';
$remote_addr = (isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : '';
 
if (!empty($client_ip)) {
/trunk/index.php
1,20 → 1,92
<?php
 
# ViaThinkSoft PHP Guestbook 2.8.1
# (C) 2003-2017 ViaThinkSoft, Daniel Marschall
# Licensed under GPL v3
# ViaThinkSoft PHP Guestbook 2.8.2
# (C) 2003-2022 ViaThinkSoft, Daniel Marschall
# Licensed under the Apache 2.0 License
 
// Version des Gästebuchs
$version = '2.8.1';
 
// START DEFAULT WERTE
 
$charset = 'ISO-8859-1';
 
// Der Titel der Seite
$seitentitel = 'Mein Gästebuch';
 
// Seitenkopf
$seitenkopf = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
 
<head>
<meta http-equiv="Content-Type" content="text/html; charset={CHARSET}" />
<title>'.htmlentities($seitentitel).' G&auml;stebuch</title>
</head>
 
<body>';
 
// Seitenfuß
$seitenfuss = '</body></html>';
 
// Farben
$farbe1 = '#505080'; // Rand eines Eintrags
$farbe2 = '#D2DAF0'; // Eintrag Segment 2 (Text) BG
$farbe3 = '#A0B1E0'; // Eintrag Segment 1 (Kopfzeile) BG
$farbe4 = '#333333'; // Erstellungsdatum Schrift
$farbe5 = '#E2E7F5'; // Eintrag Segment 3 (Admin-Kommentar, optional) BG
$farbe6 = 'red'; // Fehlermeldung
$farbe7 = 'blue'; // Pflichtfeld-Stern
$farbe8 = 'green'; // Erfolgsmeldung
$farbe9 = 'black'; // Segment 1 (Kopfzeile) Text
$farbe10 = 'black'; // Segment 2 (Text) Text
$farbe11 = 'black'; // Segment 3 (Admin-Kommentar, optional) Text
 
// Die MySQL-Zugangsdaten
$mysql_server = 'localhost';
$mysql_user = 'root';
$mysql_pass = '';
$mysql_database = 'guestbook';
 
// Die Datenbanktabellennamen
$table_entries = 'gaestebuch_entries';
$table_smileys = 'gaestebuch_smileys';
 
// E-Mail-Adresse
$adminmail = 'your_email_address@example.com';
$adminmail_cc = '';
 
// Einträge pro Seite
$eintraege_proseite = 10;
 
// Vorsicht: Der Server muss autorisiert sein, eine E-Mail zu über diese Domain zu senden (SPF/DKIM)
$cfg_from_email = 'noreply@example.com';
 
// Features
$cfg_feature_simple_antispam = true;
$cfg_automatisch_freischalten = false;
$cfg_unfreigeschaltete_anzegen = false;
$cfg_vorschau = true;
 
// Recaptcha - This is the most secure Captcha
// It also helps against "F5" spamming!
// Get a FREE API key here: https://www.google.com/recaptcha/admin/create
$cfg_recaptcha_enabled = false;
$cfg_recaptcha_pubkey = '';
$cfg_recaptcha_privkey = '';
 
// see https://daniel-lange.com/archives/66-ICQ-web-status-icons.html
$cfg_icq_statusicon = 5;
 
// ENDE DEFAULT WERTE
 
if (!file_exists(__DIR__ . '/config/config.inc.php')) {
die('ERROR: File <b>config/config.inc.php</b> does not exist. Please create it using <b>config/config.original.inc.php</b>');
}
require_once __DIR__ . '/config/config.inc.php';
 
if (!isset($cfg_recaptcha_enabled)) $cfg_recaptcha_enabled = false;
if ($cfg_recaptcha_enabled) $cfg_feature_simple_antispam = false;
if (!isset($cfg_icq_statusicon)) $cfg_icq_statusicon = 5;
 
require_once __DIR__ . '/includes/database.inc.php';
verbinden();
76,8 → 148,8
 
// Smiley pre-parsing
$uid = uniqid();
$result = mysql_query("SELECT `zeichen`, `image`, `beschreibung`, `id` FROM `".mysql_real_escape_string($table_smileys)."` WHERE `enabled` = '1' ORDER BY `id` ASC");
while ($row = mysql_fetch_object($result)) {
$result = db_query("SELECT `zeichen`, `image`, `beschreibung`, `id` FROM `".db_real_escape_string($table_smileys)."` WHERE `enabled` = '1' ORDER BY `id` ASC");
while ($row = db_fetch_object($result)) {
# $nachricht = str_replace($row->zeichen, '<img src="images/smileys/'.$row->image.'" alt="'.myhtmlentities($row->beschreibung).'" title="'.myhtmlentities($row->beschreibung).'" />', $nachricht);
$nachricht = str_replace($row->zeichen, "\nSMILEY${uid}:".$row->id.":${uid}YELIMS\n", $nachricht);
}
99,8 → 171,8
$nachricht = substr($nachricht, 1);
 
// Final smiley parsing
$result = mysql_query("SELECT `zeichen`, `image`, `beschreibung`, `id` FROM `".mysql_real_escape_string($table_smileys)."` WHERE `enabled` = '1' ORDER BY `id` ASC");
while ($row = mysql_fetch_object($result)) {
$result = db_query("SELECT `zeichen`, `image`, `beschreibung`, `id` FROM `".db_real_escape_string($table_smileys)."` WHERE `enabled` = '1' ORDER BY `id` ASC");
while ($row = db_fetch_object($result)) {
$nachricht = str_replace("<br />\nSMILEY${uid}:".$row->id.":${uid}YELIMS<br />\n", '<img src="'.$loc_dir.'images/smileys/'.$row->image.'" alt="'.myhtmlentities($row->beschreibung).'" title="'.myhtmlentities($row->beschreibung).'" />', $nachricht);
}
 
200,19 → 272,20
die('<p><font color="'.$farbe6.'">Ein Fehler ist aufgetreten. Fehler in den Parametern.</font></p>'.$seitenfuss);
}
 
$result = mysql_query("SELECT `show`, MD5(`nachricht`) AS `md5` FROM `".mysql_real_escape_string($table_entries)."` WHERE `id` = '".mysql_real_escape_string($id)."'");
$row = mysql_fetch_array($result);
if ($row['show'] == 1) {
$result = db_query("SELECT `show`, MD5(`nachricht`) AS `md5` FROM `".db_real_escape_string($table_entries)."` WHERE `id` = '".db_real_escape_string($id)."'");
if ($row = db_fetch_object($result)) {
if ($row->show == 1) {
echo '<p><font color="'.$farbe8.'">Eintrag ist bereits freigeschaltet!</font></p>';
} else {
$md5_valid = md5_valid($id, $row['md5']);
$md5_valid = md5_valid($id, $row->md5);
if (strtolower($md5) == strtolower($md5_valid)) {
mysql_query("UPDATE `".mysql_real_escape_string($table_entries)."` SET `show` = '1' WHERE `id` = '".mysql_real_escape_string($id)."'");
db_query("UPDATE `".db_real_escape_string($table_entries)."` SET `show` = '1' WHERE `id` = '".db_real_escape_string($id)."'");
echo '<p><font color="'.$farbe8.'">Eintrag erfolgreich freigeschaltet!</font></p>';
} else {
echo '<p><font color="'.$farbe6.'">Keine Berechtigung, den Eintrag freizuschalten!</font></p>';
}
}
}
 
die($seitenfuss);
}
332,44 → 405,44
echo "<a href=\"javascript:document.frm1.submit()\"><img src=\"images/buttons/abschicken.gif\" border=\"0\" height=\"31\" width=\"146\" alt=\"Abschicken\" title=\"Abschicken\" /></a>";
echo "</form>";
} else {
$daten = "'".mysql_real_escape_string($name)."'";
$daten = "'".db_real_escape_string($name)."'";
$felder = '`name`';
 
if ($ort != '') {
$daten .= ", '".mysql_real_escape_string($ort)."'";
$daten .= ", '".db_real_escape_string($ort)."'";
$felder .= ', `ort`';
}
 
if ($email != '') {
$daten .= ", '".mysql_real_escape_string($email)."'";
$daten .= ", '".db_real_escape_string($email)."'";
$felder .= ', `email`';
}
 
if ($homepage != '') {
$daten .= ", '".mysql_real_escape_string($homepage)."'";
$daten .= ", '".db_real_escape_string($homepage)."'";
$felder .= ', `homepage`';
}
 
if ($icq != '') {
$daten .= ", '".mysql_real_escape_string($icq)."'";
$daten .= ", '".db_real_escape_string($icq)."'";
$felder .= ', `icq`';
}
 
$daten .= ", '".mysql_real_escape_string("$datum $zeit")."'";
$daten .= ", '".db_real_escape_string("$datum $zeit")."'";
$felder .= ', `timestamp`';
 
$daten .= ", '".mysql_real_escape_string($ip)."'";
$daten .= ", '".db_real_escape_string($ip)."'";
$felder .= ', `ip`';
 
$daten .= ", '".mysql_real_escape_string($nachricht)."'";
$daten .= ", '".db_real_escape_string($nachricht)."'";
$felder .= ', `nachricht`';
 
$show = $cfg_automatisch_freischalten ? '1' : '0';
$daten .= ", '".mysql_real_escape_string($show)."'";
$daten .= ", '".db_real_escape_string($show)."'";
$felder .= ', `show`';
 
$result = mysql_query("INSERT INTO `".mysql_real_escape_string($table_entries)."` ($felder) VALUES ($daten)");
$id = mysql_insert_id();
$result = db_query("INSERT INTO `".db_real_escape_string($table_entries)."` ($felder) VALUES ($daten)");
$id = db_insert_id();
 
$md5 = md5($nachricht);
$md5_valid = md5_valid($id, $md5);
442,7 → 515,7
$h->addHeader('Reply-To', $email);
}
 
if ((isset($adminmail_cc)) && ($adminmail_cc != '')) {
if ($adminmail_cc != '') {
$h->addHeader('CC', $adminmail_cc);
}
 
472,7 → 545,7
</div>';
 
} else {
echo "<p>".mysql_error()."</p>";
echo "<p>".db_error()."</p>";
echo '<p><font color="'.$farbe6.'">Es ist ein schwerer Fehler aufgetreten. Versuchen Sie es nocheinmal.</font></p>';
}
}
489,7 → 562,7
echo ' Die Eintr&auml;ge werden erst nach einer Pr&uuml;fung ver&ouml;ffentlicht.';
echo '</p>';
 
if (isset($relfehler)) {
if ($relfehler != '') {
echo "<p>$relfehler</p>";
}
 
591,8 → 664,8
// -->
</script>';
 
$result = mysql_query("SELECT `zeichen`, `image`, `beschreibung` FROM `".mysql_real_escape_string($table_smileys)."` WHERE `enabled` = '1' AND `show_in_editor` = '1' ORDER BY `id` ASC");
while ($row = mysql_fetch_object($result)) {
$result = db_query("SELECT `zeichen`, `image`, `beschreibung` FROM `".db_real_escape_string($table_smileys)."` WHERE `enabled` = '1' AND `show_in_editor` = '1' ORDER BY `id` ASC");
while ($row = db_fetch_object($result)) {
echo "<a href=\"javascript:setsmiley(' ".addslashes(myhtmlentities($row->zeichen))." ')\">".
'<img src="images/smileys/'.$row->image.'" border="0" alt="'.myhtmlentities($row->beschreibung).'" title="'.myhtmlentities($row->beschreibung).'" /></a>&nbsp;';
}
645,19 → 718,19
 
$cond = ($cfg_unfreigeschaltete_anzegen) ? '' : " WHERE `show` = '1'";
 
$result = mysql_query("SELECT * FROM `".mysql_real_escape_string($table_entries)."`$cond");
if ($result) $number = mysql_num_rows($result); else $number = 0;
$result = db_query("SELECT * FROM `".db_real_escape_string($table_entries)."`$cond");
if ($result) $number = db_num_rows($result); else $number = 0;
$max_page = ceil($number / $eintraege_proseite);
 
$seiten = isset($_REQUEST['seiten']) ? $_REQUEST['seiten'] : 1;
if (!isset($seiten) || ($seiten > $max_page) || ($seiten < 0)) $seiten = '1';
 
$result = mysql_query("SELECT * FROM `".mysql_real_escape_string($table_entries)."`$cond ORDER BY `id` DESC LIMIT ".($seiten-1)*$eintraege_proseite.",".$eintraege_proseite);
$result = db_query("SELECT * FROM `".db_real_escape_string($table_entries)."`$cond ORDER BY `id` DESC LIMIT ".($seiten-1)*$eintraege_proseite.",".$eintraege_proseite);
 
$keineeintraege = true;
 
if ($result) {
while ($row = mysql_fetch_object($result)) {
while ($row = db_fetch_object($result)) {
$xry = explode(' ', $row->timestamp);
$datum = $xry[0];
$zeit = $xry[1];
/trunk/phpstan.neon.dist
0,0 → 1,19
parameters:
level: 5
fileExtensions:
- php
- phps
paths:
- .
excludePaths:
analyse:
- includes/recaptcha
analyseAndScan:
- .phpstan.tmp
tmpDir: .phpstan.tmp
bootstrapFiles:
- config/config.original.inc.php
ignoreErrors:
- '#is always (true|false)\.#'
#- '#Call to function assert\(\) with false will always evaluate to false\.#'
#- '#with no typehint specified\.#'
/trunk
Property changes:
Modified: svn:ignore
+.phpstan.tmp
_private