ajax-chat/src/AJAXChatTemplate.php
2022-07-03 21:04:54 +00:00

362 lines
15 KiB
PHP

<?php
/*
* @package AJAX_Chat
* @author Sebastian Tschan
* @copyright (c) Sebastian Tschan
* @license GNU Affero General Public License
* @link https://blueimp.net/ajax/
*/
// Class to handle HTML templates
class AJAXChatTemplate {
private $ajaxChat;
private $_regExpTemplateTags;
private $_templateFile;
private $_contentType;
private $_content;
private $_parsedContent;
// Constructor:
function __construct(&$ajaxChat, $templateFile, $contentType=null) {
$this->ajaxChat = $ajaxChat;
$this->_regExpTemplateTags = '/\[(\w+?)(?:(?:\/)|(?:\](.+?)\[\/\1))\]/s';
$this->_templateFile = $templateFile;
$this->_contentType = $contentType;
}
function getParsedContent() {
if(!$this->_parsedContent) {
$this->parseContent();
}
return $this->_parsedContent;
}
function getContent() {
if(!$this->_content) {
$this->_content = AJAXChatFileSystem::getFileContents($this->_templateFile);
}
return $this->_content;
}
function parseContent() {
$this->_parsedContent = $this->getContent();
// Remove the XML declaration if the content-type is not xml:
if($this->_contentType && (strpos($this->_contentType,'xml') === false)) {
$doctypeStart = strpos($this->_parsedContent, '<!DOCTYPE ');
if($doctypeStart !== false) {
// Removing the XML declaration (in front of the document type) prevents IE<7 to go into "Quirks mode":
$this->_parsedContent = substr($this->_parsedContent, $doctypeStart);
}
}
// Replace template tags ([TAG/] and [TAG]content[/TAG]) and return parsed template content:
$this->_parsedContent = preg_replace_callback($this->_regExpTemplateTags, array($this, 'replaceTemplateTags'), $this->_parsedContent);
}
function replaceTemplateTags($tagData) {
switch($tagData[1]) {
case 'AJAX_CHAT_URL':
return $this->ajaxChat->htmlEncode($this->ajaxChat->getChatURL());
case 'CONF':
return $this->ajaxChat->getConfig(...explode('.', $tagData[2], 2));
case 'LANG':
return $this->ajaxChat->htmlEncode($this->ajaxChat->getLang($tagData[2]));
case 'LANG_CODE':
return $this->ajaxChat->getLangCode();
case 'BASE_DIRECTION':
return $this->getBaseDirectionAttribute();
case 'CONTENT_ENCODING':
return $this->ajaxChat->getConfig('contentEncoding');
case 'CONTENT_TYPE':
return $this->_contentType;
case 'LOGIN_URL':
return ($this->ajaxChat->getRequestVar('view') == 'logs') ? './?view=logs' : './';
case 'USER_NAME_MAX_LENGTH':
return $this->ajaxChat->getConfig('userNameMaxLength');
case 'MESSAGE_TEXT_MAX_LENGTH':
return $this->ajaxChat->getConfig('messageTextMaxLength');
case 'LOGIN_CHANNEL_ID':
return $this->ajaxChat->getValidRequestChannelID();
case 'SESSION_NAME':
return $this->ajaxChat->getConfig('sessionName');
case 'COOKIE_EXPIRATION':
return $this->ajaxChat->getConfig('sessionCookieLifeTime');
case 'COOKIE_PATH':
return $this->ajaxChat->getConfig('sessionCookiePath');
case 'COOKIE_DOMAIN':
return $this->ajaxChat->getConfig('sessionCookieDomain');
case 'COOKIE_SECURE':
return $this->ajaxChat->getConfig('sessionCookieSecure');
case 'CHAT_BOT_NAME':
return rawurlencode($this->ajaxChat->getConfig('chatBotName'));
case 'CHAT_BOT_ID':
return $this->ajaxChat->getConfig('chatBotID');
case 'ALLOW_USER_MESSAGE_DELETE':
if($this->ajaxChat->getConfig('allowUserMessageDelete'))
return 1;
else
return 0;
case 'INACTIVE_TIMEOUT':
return $this->ajaxChat->getConfig('inactiveTimeout');
case 'PRIVATE_CHANNEL_DIFF':
return $this->ajaxChat->getConfig('privateChannelDiff');
case 'PRIVATE_MESSAGE_DIFF':
return $this->ajaxChat->getConfig('privateMessageDiff');
case 'SHOW_CHANNEL_MESSAGES':
if($this->ajaxChat->getConfig('showChannelMessages'))
return 1;
else
return 0;
case 'SOCKET_SERVER_ENABLED':
if($this->ajaxChat->getConfig('socketServerEnabled'))
return 1;
else
return 0;
case 'SOCKET_SERVER_HOST':
if($this->ajaxChat->getConfig('socketServerHost')) {
$socketServerHost = $this->ajaxChat->getConfig('socketServerHost');
} else {
$socketServerHost = (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']);
}
return rawurlencode($socketServerHost);
case 'SOCKET_SERVER_PORT':
return $this->ajaxChat->getConfig('socketServerPort');
case 'SOCKET_SERVER_CHAT_ID':
return $this->ajaxChat->getConfig('socketServerChatID');
case 'STYLE_SHEETS':
return $this->getStyleSheetLinkTags();
case 'CHANNEL_OPTIONS':
return $this->getChannelOptionTags();
case 'STYLE_OPTIONS':
return $this->getStyleOptionTags();
case 'LANGUAGE_OPTIONS':
return $this->getLanguageOptionTags();
case 'ERROR_MESSAGES':
return $this->getErrorMessageTags();
case 'LOGS_CHANNEL_OPTIONS':
return $this->getLogsChannelOptionTags();
case 'LOGS_YEAR_OPTIONS':
return $this->getLogsYearOptionTags();
case 'LOGS_MONTH_OPTIONS':
return $this->getLogsMonthOptionTags();
case 'LOGS_DAY_OPTIONS':
return $this->getLogsDayOptionTags();
case 'LOGS_HOUR_OPTIONS':
return $this->getLogsHourOptionTags();
case 'MENU_BAR':
return <<<EOF
<ul>
<li class="first notcurrent"><a href="{$this->ajaxChat->getConfig('flashiiUrl', 'home')}">Home</a></li>
<li class="notcurrent"><a href="{$this->ajaxChat->getConfig('flashiiUrl', 'news')}">News</a></li>
<li class="current"><a href="./">Chat</a></li>
<li class="notcurrent"><a href="{$this->ajaxChat->getConfig('flashiiUrl', 'members')}">Members</a></li>
<li class="notcurrent"><a href="{$this->ajaxChat->getConfig('flashiiUrl', 'donate')}">Donate</a></li>
<li class="notcurrent"><a href="{$this->ajaxChat->getConfig('flashiiUrl', 'status')}">Status</a></li>
</ul>
EOF;
case 'COPYRIGHT':
return <<<EOF
<div class="copyright">
Copyright &copy; 2013-2015 <a href="https://flash.moe/" target="_blank">Flashwave</a>
<br /><a href="https://blueimp.net/ajax/" target="_blank">AJAX Chat</a> &copy; <a href="https://blueimp.net" target="_blank">blueimp.net</a>
<br />
<a href="{$this->ajaxChat->getConfig('flashiiUrl', 'feedback')}">Feedback</a> |
<a href="{$this->ajaxChat->getConfig('flashiiUrl', 'changelog')}">Changelog</a> |
<a href="{$this->ajaxChat->getConfig('flashiiUrl', 'rules')}">Rules &amp; Info</a> |
<a href="{$this->ajaxChat->getConfig('flashiiUrl', 'terms')}">Terms of Service</a> |
<a href="{$this->ajaxChat->getConfig('flashiiUrl', 'contact')}">Contact</a> |
<a href="{$this->ajaxChat->getConfig('flashiiUrl', 'test')}">DevSite</a> |
<a href="?view=legacy">Legacy Login</a>
</div><br />
EOF;
case 'SANDSTORM':
if(date('md') === '0127' || !empty($_GET['sandstorm']))
return <<<HTML
<br />
<audio loop="loop" autoplay="autoplay" controls="controls">
<source type="audio/ogg" src="./sandstorm.ogg" />
<source type="audio/mpeg" src="./sandstorm.mp3" />
</audio>
<br />
HTML;
else
return '';
default:
return $this->ajaxChat->replaceCustomTemplateTags($tagData[1], (isset($tagData[2]) ? $tagData[2] : null));
}
}
// Function to display alternating table row colors:
function alternateRow($rowOdd='rowOdd', $rowEven='rowEven') {
static $i;
$i += 1;
if($i % 2 == 0) {
return $rowEven;
} else {
return $rowOdd;
}
}
function getBaseDirectionAttribute() {
$langCodeParts = explode('-', $this->ajaxChat->getLangCode());
switch($langCodeParts[0]) {
case 'ar':
case 'fa':
case 'he':
return 'rtl';
default:
return 'ltr';
}
}
function getStyleSheetLinkTags() {
$styleSheets = '';
foreach($this->ajaxChat->getConfig('styleAvailable') as $style) {
$alternate = ($style == $this->ajaxChat->getConfig('styleDefault')) ? '' : 'alternate ';
$styleSheets .= '<link rel="'.$alternate.'stylesheet" type="text/css" href="css/'.rawurlencode($style).'.ajaxchat.css" title="'.$this->ajaxChat->htmlEncode($style).'"/>';
}
return $styleSheets;
}
function getChannelOptionTags() {
$channelOptions = '';
$channelSelected = false;
foreach($this->ajaxChat->getChannels() as $key=>$value) {
if($this->ajaxChat->isLoggedIn()) {
$selected = ($value == $this->ajaxChat->getChannel()) ? ' selected="selected"' : '';
} else {
$selected = ($value == $this->ajaxChat->getConfig('defaultChannelID')) ? ' selected="selected"' : '';
}
if($selected) {
$channelSelected = true;
}
$channelOptions .= '<option value="'.$this->ajaxChat->htmlEncode($key).'"'.$selected.'>'.$this->ajaxChat->htmlEncode($key).'</option>';
}
if($this->ajaxChat->isLoggedIn() && $this->ajaxChat->isAllowedToCreatePrivateChannel()) {
// Add the private channel of the user to the options list:
if(!$channelSelected && $this->ajaxChat->getPrivateChannelID() == $this->ajaxChat->getChannel()) {
$selected = ' selected="selected"';
$channelSelected = true;
} else {
$selected = '';
}
$privateChannelName = $this->ajaxChat->getPrivateChannelName();
$channelOptions .= '<option value="'.$this->ajaxChat->htmlEncode($privateChannelName).'"'.$selected.'>'.$this->ajaxChat->htmlEncode($privateChannelName).'</option>';
}
// If current channel is not in the list, try to retrieve the channelName:
if(!$channelSelected) {
$channelName = $this->ajaxChat->getChannelName();
if($channelName !== null) {
$channelOptions .= '<option value="'.$this->ajaxChat->htmlEncode($channelName).'" selected="selected">'.$this->ajaxChat->htmlEncode($channelName).'</option>';
} else {
// Show an empty selection:
$channelOptions .= '<option value="" selected="selected">---</option>';
}
}
return $channelOptions;
}
function getStyleOptionTags() {
$styleOptions = '';
foreach($this->ajaxChat->getConfig('styleAvailable') as $style) {
$selected = ($style == $this->ajaxChat->getConfig('styleDefault')) ? ' selected="selected"' : '';
$styleOptions .= '<option value="'.$this->ajaxChat->htmlEncode($style).'"'.$selected.'>'.$this->ajaxChat->htmlEncode($style).'</option>';
}
return $styleOptions;
}
function getLanguageOptionTags() {
$languageOptions = '';
$languageNames = $this->ajaxChat->getConfig('langNames');
foreach($this->ajaxChat->getConfig('langAvailable') as $langCode) {
$selected = ($langCode == $this->ajaxChat->getLangCode()) ? ' selected="selected"' : '';
$languageOptions .= '<option value="'.$this->ajaxChat->htmlEncode($langCode).'"'.$selected.'>'.$languageNames[$langCode].'</option>';
}
return $languageOptions;
}
function getErrorMessageTags() {
$errorMessages = '';
foreach($this->ajaxChat->getInfoMessages('error') as $error) {
$errorMessages .= '<h3 class="miotitle">'.$this->ajaxChat->htmlEncode($this->ajaxChat->getLang($error)).'</h3>';
}
return $errorMessages;
}
function getLogsChannelOptionTags() {
$channelOptions = '';
$channelOptions .= '<option value="-3">------</option>';
foreach($this->ajaxChat->getChannels() as $key=>$value) {
if($this->ajaxChat->getUserRole() != AJAX_CHAT_ADMIN && $this->ajaxChat->getConfig('logsUserAccessChannelList') && !in_array($value, $this->ajaxChat->getConfig('logsUserAccessChannelList'))) {
continue;
}
$channelOptions .= '<option value="'.$value.'">'.$this->ajaxChat->htmlEncode($key).'</option>';
}
$channelOptions .= '<option value="-1">'.$this->ajaxChat->htmlEncode($this->ajaxChat->getLang('logsPrivateChannels')).'</option>';
$channelOptions .= '<option value="-2">'.$this->ajaxChat->htmlEncode($this->ajaxChat->getLang('logsPrivateMessages')).'</option>';
return $channelOptions;
}
function getLogsYearOptionTags() {
$yearOptions = '';
$yearOptions .= '<option value="-1">----</option>';
for($year=date('Y'); $year>=$this->ajaxChat->getConfig('logsFirstYear'); $year--) {
$yearOptions .= '<option value="'.$year.'">'.$year.'</option>';
}
return $yearOptions;
}
function getLogsMonthOptionTags() {
$monthOptions = '';
$monthOptions .= '<option value="-1">--</option>';
for($month=1; $month<=12; $month++) {
$monthOptions .= '<option value="'.$month.'">'.sprintf("%02d", $month).'</option>';
}
return $monthOptions;
}
function getLogsDayOptionTags() {
$dayOptions = '';
$dayOptions .= '<option value="-1">--</option>';
for($day=1; $day<=31; $day++) {
$dayOptions .= '<option value="'.$day.'">'.sprintf("%02d", $day).'</option>';
}
return $dayOptions;
}
function getLogsHourOptionTags() {
$hourOptions = '';
$hourOptions .= '<option value="-1">-----</option>';
for($hour=0; $hour<=23; $hour++) {
$hourOptions .= '<option value="'.$hour.'">'.sprintf("%02d", $hour).':00</option>';
}
return $hourOptions;
}
}