Скрипт форума на PHP своими руками. Часть 9
Кроме того, что пользователи могут обмениваться личными сообщениями, они могут еще написать письмо через форум. Функция getSendMailForm() возвращает html формы для отправки письма через форум:
<?php
// Функция возвращает html формы для отправки письма через форум
function getSendMailForm()
{
// Если письмо пытается отправить незарегистрированный пользователь
if ( !isset( $_SESSION['user'] ) ) {
header( 'Location: '.$_SERVER['PHP_SELF'] );
die();
}
$html = '';
$toUser = '';
if ( isset( $_GET['idUser'] ) ) {
$id = (int)$_GET['idUser'];
if ( $id > 0 ) {
$query = "SELECT name FROM ".TABLE_USERS." WHERE id_author=".$id;
$res = mysql_query( $query );
if ( $res ) {
if ( mysql_num_rows( $res ) > 0 ) $toUser = mysql_result( $res, 0, 0 );
}
}
}
$subject = '';
$message = '';
$action = $_SERVER['PHP_SELF'].'?action=sendMail';
// Если при заполнении формы были допущены ошибки
if ( isset( $_SESSION['sendMailForm'] ) ) {
$info = file_get_contents( './templates/infoMessage.html' );
$info = str_replace( '{infoMessage}', $_SESSION['sendMailForm']['error'], $info );
$html = $html.$info."\n";
$toUser = htmlspecialchars( $_SESSION['sendMailForm']['toUser'] );
$subject = htmlspecialchars( $_SESSION['sendMailForm']['subject'] );
$message = htmlspecialchars( $_SESSION['sendMailForm']['message'] );
unset( $_SESSION['sendMailForm'] );
}
$tpl = file_get_contents( 'templates/sendMailForm.html' );
$tpl = str_replace( '{action}', $action, $tpl );
$tpl = str_replace( '{toUser}', $toUser, $tpl );
$tpl = str_replace( '{subject}', $subject, $tpl );
$tpl = str_replace( '{message}', $message, $tpl );
$html = $html.$tpl;
return $html;
}
?>
Обработчик формы - функция sendMail():
<?php
// Отправка письма пользователю сайта
function sendMail()
{
// Если не переданы данные формы - функция вызвана по ошибке
if ( !isset( $_POST['toUser'] ) or
!isset( $_POST['subject'] ) or
!isset( $_POST['message'] ) )
{
header( 'Location: '.$_SERVER['PHP_SELF'] );
die();
}
// Если письмо пытается отправить незарегистрированный пользователь
if ( !isset( $_SESSION['user'] ) ) {
header( 'Location: '.$_SERVER['PHP_SELF'] );
die();
}
// Обрезаем переменные до длины, указанной в параметре maxlength тега input
$toUser = substr( $_POST['toUser'], 0, 30 );
$subject = substr( $_POST['subject'], 0, 60 );
$message = substr( $_POST['message'], 0, MAX_MAILBODY_LENGTH );
// Обрезаем лишние пробелы
$toUser = trim( $toUser );
$subject = trim( $subject );
$message = trim( $message );
// Проверяем, заполнены ли обязательные поля
$error = '';
if ( empty( $toUser ) ) $error = $error.'<li>не заполнено поле "Для пользователя"</li>'."\n";
if ( empty( $subject ) ) $error = $error.'<li>не заполнено поле "Заголовок письма"</li>'."\n";
if ( empty( $message ) ) $error = $error.'<li>не заполнено поле "Текст письма"</li>'."\n";
// Проверяем поля формы на недопустимые символы
if ( !empty( $toUser ) and !preg_match( "#^[- _0-9a-zА-Яа-я]+$#i", $toUser ) )
$error = $error.'<li>поле "Для пользователя" содержит недопустимые символы</li>'."\n";
if ( !empty( $subject ) and !preg_match( "#^[-.;:,?!\/)(_\"\s0-9а-яА-Яa-z]+$#i", $subject ) )
$error = $error.'<li>поле "Заголовок письма" содержит недопустимые символы</li>'."\n";
// Проверяем, есть ли такой пользователь
if ( !empty( $toUser ) ) {
$to = preg_replace( "#[^- _0-9a-zа-яА-Я]#i", '', $toUser );
$query = "SELECT id_author, name, email FROM ".TABLE_USERS." WHERE name='".$to."' LIMIT 1";
$res = mysql_query( $query );
if ( !$res ) {
$msg = 'Произошла ошибка при отправке письма';
$err = 'Ошибка при выполнении запроса: <br/>'.
$query.'<br/>'.mysql_errno().': '.mysql_error().'<br/>'.
'(Файл '. __FILE__ .', строка '. __LINE__ .')';
return showErrorMessage( $msg, $err, true, '' );
}
if ( mysql_num_rows( $res ) == 0 )
$error = $error.'<li>пользователь с именем <strong>'.$to.'</strong> не зарегистрирован</li>'."\n";
}
// Если были допущены ошибки при заполнении формы -
// перенаправляем посетителя для исправления ошибок
if ( !empty( $error ) )
{
$_SESSION['sendMailForm'] = array();
$_SESSION['sendMailForm']['error'] = '<p class="errorMsg">При заполнениии формы были допущены ошибки:</p>'.
"\n".'<ul class="errorMsg">'."\n".$error.'</ul>'."\n";
$_SESSION['sendMailForm']['toUser'] = $toUser;
$_SESSION['sendMailForm']['subject'] = $subject;
$_SESSION['sendMailForm']['message'] = $message;
header( 'Location: '.$_SERVER['PHP_SELF'].'?action=sendMailForm' );
die();
}
$toUser = mysql_fetch_array( $res );
$fromUser = $_SESSION['user']['name'];
$message = 'ОТ: '.$fromUser."\n".'ТЕМА: '.$subject."\n\n".$message;
// формируем заголовки письма
$headers = "From: ".$_SERVER['SERVER_NAME']." <".ADMIN_EMAIL.">\n";
$headers = $headers."Content-type: text/plain; charset=\"windows-1251\"\n";
$headers = $headers."Return-path: <".ADMIN_EMAIL.">\n";
$subject = 'Письмо с форума '.$_SERVER['SERVER_NAME'].' от '.$fromUser;
$subject = '=?koi8-r?B?'.base64_encode(convert_cyr_string($subject, "w","k")).'?=';
if ( mail( $toUser['email'], $subject, $message, $headers ) )
return showInfoMessage( 'Ваше письмо успешно отправлено', '' );
else
return showInfoMessage( 'Произошла ошибка при отправке письма', '' );
}
?>
Перед тем как рассматривать систему администрирования форума, давайте бросим взгляд на несколько вспомогательных функций. Функция print_page() отвечает за обработку BB-кодов:
<?php
// Функция обработки bbCode
function print_page($message)
{
// Разрезаем слишком длинные слова
$message = preg_replace_callback(
"|([a-zа-я\d!]{35,})|i",
"split_text",
$message);
// Тэги - [code], [php]
preg_match_all( "#\[php\](.+)\[\/php\]#isU", $message, $matches );
$cnt = count( $matches[0] );
for ( $i = 0; $i < $cnt; $i++ ) {
$phpBlocks[] = '<div class="codePHP">'.highlight_string( $matches[1][$i], true ).'</div>';
$uniqidPHP = '[php_'.uniqid('').']';
$uniqidsPHP[] = $uniqidPHP;
$message = str_replace( $matches[0][$i], $uniqidPHP, $message );
}
$spaces = array( ' ', "\t" );
$entities = array( ' ', ' ' );
preg_match_all( "#\[code\](.+)\[\/code\]#isU", $message, $matches );
$cnt = count( $matches[0] );
for ( $i = 0; $i < $cnt; $i++ ) {
$codeBlocks[] = '<div class="code">'.nl2br( str_replace( $spaces, $entities, htmlspecialchars( $matches[1][$i] ) ) ).'</div>';
$uniqidCode = '[code_'.uniqid('').']';
$uniqidsCode[] = $uniqidCode;
$message = str_replace( $matches[0][$i], $uniqidCode, $message );
}
$message = htmlspecialchars( $message );
$message = preg_replace("#\[b\](.+)\[\/b\]#isU", '<b>\\1</b>', $message);
$message = preg_replace("#\[i\](.+)\[\/i\]#isU", '<i>\\1</i>', $message);
$message = preg_replace("#\[u\](.+)\[\/u\]#isU", '<u>\\1</u>', $message);
$message = preg_replace("#\[quote\](.+)\[\/quote\]#isU",'<div class="quoteHead">Цитата</div><div class="quoteContent">\\1</div>',$message);
$message = preg_replace("#\[quote="([- 0-9a-zа-яА-Я]{1,30})"\](.+)\[\/quote\]#isU", '<div class="quoteHead">\\1 пишет:</div><div class="quoteContent">\\2</div>', $message);
$message = preg_replace("#\[url\][\s]*([\S]+)[\s]*\[\/url\]#isU",'<a href="\\1" target="_blank">\\1</a>',$message);
$message = preg_replace("#\[url[\s]*=[\s]*([\S]+)[\s]*\][\s]*([^\[]*)\[/url\]#isU",
'<a href="\\1" target="_blank">\\2</a>',
$message);
$message = preg_replace("#\[img\][\s]*([\S]+)[\s]*\[\/img\]#isU",'<img src="\\1" alt="" />',$message);
$message = preg_replace("#\[color=red\](.+)\[\/color\]#isU",'<span style="color:#FF0000">\\1</span>',$message);
$message = preg_replace("#\[color=green\](.+)\[\/color\]#isU",'<span style="color:#008000">\\1</span>',$message);
$message = preg_replace("#\[color=blue\](.+)\[\/color\]#isU",'<span style="color:#0000FF">\\1</span>',$message);
$message = preg_replace_callback("#\[list\]\s*((?:\[\*\].+)+)\[\/list\]#siU",'getUnorderedList',$message);
$message = preg_replace_callback("#\[list=([a|1])\]\s*((?:\[\*\].+)+)\[\/list\]#siU", 'getOrderedList',$message);
$message = nl2br( $message);
if ( isset( $uniqidCode ) ) $message = str_replace( $uniqidsCode, $codeBlocks, $message );
if ( isset( $uniqidPHP ) ) $message = str_replace( $uniqidsPHP, $phpBlocks, $message );
return $message;
}
function split_text($matches)
{
return wordwrap($matches[1], 35, ' ',1);
}
function getUnorderedList( $matches )
{
$list = '<ul>';
$tmp = trim( $matches[1] );
$tmp = substr( $tmp, 3 );
$tmpArray = explode( '', $tmp );
$elements = '';
foreach ( $tmpArray as $value ) {
$elements = $elements.'<li>'.trim($value).'</li>';
}
$list = $list.$elements;
$list = $list.'</ul>';
return $list;
}
function getOrderedList( $matches )
{
if ( $matches[1] == '1' )
$list = '<ol type="1">';
else
$list = '<ol type="a">';
$tmp = trim( $matches[2] );
$tmp = substr( $tmp, 3 );
$tmpArray = explode( '', $tmp );
$elements = '';
foreach ( $tmpArray as $value ) {
$elements = $elements.'<li>'.trim($value).'</li>';
}
$list = $list.$elements;
$list = $list.'</ol>';
return $list;
}
?>
Функция getStat() отвечает за вывод статистики форума: общее количество оставленных сообщений, число зарегистрированных пользователей и т.п.
<?php
// Статистика форума
function getStat()
{
$html = '<table class="showTable">'."\n";
$html = $html.'<tr><th>Статистика</th></tr>'."\n";
$html = $html.'<tr>'."\n";
$html = $html.'<td>'."\n";
$html = $html.'<div class="details">'."\n";
$query = 'SELECT COUNT(*) FROM '.TABLE_POSTS;
$res = mysql_query( $query );
if ( !$res ) return '';
$html = $html.'Наши пользователи оставили сообщений: '.mysql_result( $res, 0, 0 ).'<br/>'."\n";
$query = 'SELECT COUNT(*) FROM '.TABLE_USERS;
$res = mysql_query( $query );
if ( !$res ) return '';
$html = $html.'Всего зарегистрированных пользователей: '.mysql_result( $res, 0, 0 ).'<br/>'."\n";
$query = 'SELECT id_author, name FROM '.TABLE_USERS.' ORDER BY id_author DESC LIMIT 1';
$res = mysql_query( $query );
if ( !$res ) return '';
list( $id_user, $name ) = mysql_fetch_array( $res );
$html = $html.'Последний зарегистрированный пользователь: '.
'<a href="'.$_SERVER['PHP_SELF'].'?action=showUserInfo&idUser='.
$id_user.'">'.$name.'</a><br/>'."\n";
// Пользователи on-line
if ( isset( $_SESSION['usersOnLine'] ) ) {
$cnt = count( $_SESSION['usersOnLine'] );
$onLine = '';
if ( $cnt > 0 ) {
$onLine = $onLine.'Сейчас на форуме: ';
foreach ( $_SESSION['usersOnLine'] as $id => $name ) {
$onLine = $onLine.'<a href="'.$_SERVER['PHP_SELF'].
'?action=showUserInfo&idUser='.$id.'">'.$name.'</a>, ';
}
$onLine = substr( $onLine, 0, (strlen( $onLine )-2) );
}
$html = $html.$onLine."\n";
}
$html = $html.'</div>'."\n";
$html = $html.'</td>'."\n";
$html = $html.'</tr>'."\n";
$html = $html.'</table>'."\n";
return $html;
}
// Функция помещает в массив $_SESSION['usersOnLine'] список зарегистрированных
// пользователей, которые в настоящий момент просматривают форум
function getUsersOnLine()
{
$query = "SELECT id_author, name
FROM ".TABLE_USERS."
WHERE UNIX_TIMESTAMP(last_visit)>".( time() - 60 * TIME_ON_LINE )."
ORDER BY status DESC";
$res = mysql_query( $query );
if ( $res ) {
if ( isset( $_SESSION['usersOnLine'] ) ) unset( $_SESSION['usersOnLine'] );
$cnt = mysql_num_rows( $res );
if ( $cnt > 0 ) {
for ( $i = 0; $on = mysql_fetch_array( $res ); $i++ ) {
$_SESSION['usersOnLine'][$on['id_author']] = $on['name'];
}
}
}
return;
}
?>
Продолжение следует...
|