<?php
declare(strict_types=1);
class Chatbox
{
/**
* Crypto Chatbox.
*
* @author Martin Latter
* @copyright Martin Latter, September 2013
* @version 2.05
* @license GNU GPL version 3.0 (GPL v3); http://www.gnu.org/licenses/gpl.html
* @link https://github.com/Tinram/CChat.git
*/
const DEBUG = false;
const DB_HOST = 'localhost';
const DB_NAME = 'cchat';
const DB_TABLE = 'chatbox';
const DB_USERNAME = 'messenger';
const DB_PASSWORD = 'P@55w0rd';
const MESSAGE_BUFFER = 3600; # 1 hour of messages displayed
const BR = '<br>';
const LB = '~';
/**
* Connect to the database.
*
* @return mysqli object
*/
private static function getConnection(): mysqli
{
$oConnection = new mysqli(self::DB_HOST, self::DB_USERNAME, self::DB_PASSWORD, self::DB_NAME);
if ($oConnection->connect_errno > 0)
{
die('Connection failed: ' . $oConnection->connect_errno . ') ' . $oConnection->connect_error);
}
return $oConnection;
}
/**
* Output chatbox message.
*
* @return string
*/
public static function outputMessages(): string
{
$iTime = time() - self::MESSAGE_BUFFER;
$sOutput = '';
$sTemp = '';
$oConn = self::getConnection();
$sQuery = '
SELECT name, message
FROM ' . self::DB_TABLE . '
WHERE date > ' . $iTime;
$rResults = $oConn->query($sQuery);
while ($aResults = $rResults->fetch_assoc())
{
$sOutput .= stripslashes($aResults['name']) . ': ';
$sTemp = $aResults['message'];
$sTemp = '<span class="m">' . $sTemp . '</span>';
$sOutput .= stripslashes($sTemp);
$sOutput .= self::BR;
}
$rResults->close();
$oConn->close();
return $sOutput;
}
/**
* Check for new chatbox message.
*
* @return string
*/
public static function checkForUpdate(): string
{
if ( ! isset($_POST['id']))
{
exit;
}
$sOutput = '';
$sTemp = '';
$oConn = self::getConnection();
$sID = self::dbSafe($_POST['id'], $oConn);
if ($sID !== '0')
{
$sQuery = '
SELECT id
FROM ' . self::DB_TABLE .'
WHERE id > ' . $sID;
$rResults = $oConn->query($sQuery);
$aResults = $rResults->fetch_row();
if ( ! $aResults) # no new messages
{
$a = array('id' => $sID, 'n' => '', 'm' => '');
$sOutput .= '[' . json_encode($a) . ']';
}
else # new messages
{
$aJSON = array();
$sQuery = '
SELECT id, name, message
FROM ' . self::DB_TABLE . '
WHERE id > ' . $sID;
$rResults = $oConn->query($sQuery); # need to query again, else blank results between browser windows
while ($aResults = $rResults->fetch_assoc())
{
$sTemp = str_ireplace(self::LB, self::BR, $aResults['message']);
$aJSON[] = json_encode(array('id' => $aResults['id'], 'n' => $aResults['name'], 'm' => $sTemp));
}
$sOutput .= '[' . join(',', $aJSON) . ']';
$rResults->close();
$oConn->close();
}
}
else
{
$sQuery = '
SELECT id
FROM ' . self::DB_TABLE . '
ORDER BY id
DESC LIMIT 1';
$rResults = $oConn->query($sQuery);
$aResult = $rResults->fetch_row();
$sID = $aResult[0];
$rResults->close();
$oConn->close();
$a = array('id' => $sID, 'n' => '', 'm' => '');
$sOutput .= '[' . json_encode($a) . ']';
}
return $sOutput;
}
/**
* Add a chatbox message to the database.
*
* @return string|null
*/
public static function addMessage(): ?string
{
if ( ! isset($_POST['n']))
{
return '';
}
$bInsertion = false;
$oConn = self::getConnection();
$sName = self::dbSafe(rawurldecode($_POST['n']), $oConn);
$sMessage = self::dbSafe($_POST['m'], $oConn);
$iDate = time();
$sInsert = '
INSERT INTO ' . self::DB_TABLE . '
(name, message, date)
VALUES(?, ?, ?)';
$oStmt = $oConn->stmt_init();
$oStmt->prepare($sInsert);
$oStmt->bind_param('ssi', $sName, $sMessage, $iDate);
$oStmt->execute();
if ($oStmt->affected_rows)
{
$bInsertion = true;
}
$iID = $oStmt->insert_id; # find ID from insert
$oStmt->close();
$oConn->close();
if ($bInsertion)
{
$a = array('id' => $iID, 'n' => $sName, 'm' => $sMessage);
$sOutput = json_encode($a); # NB no square brackets
return $sOutput;
}
else
{
if (self::DEBUG)
{
return 'Row could not be inserted into table.';
}
else
{
return null;
}
}
}
/**
* Sanitize string for database input.
*
* @param string $sExt, external string to be sanitized
* @param object $oConn, database connection
*
* @return string
*/
private static function dbSafe($sExt, mysqli &$oConn): string
{
return $oConn->real_escape_string(strip_tags(stripslashes(trim($sExt))));
}
}
|