PHP

Скрипт форума на PHP своими руками. Часть 8

В этой статье мы рассмотрим сервис Personal Messages (PM) для личного общения зарегистрированных пользователей форума. Функция getSendMsgForm() возвращает html формы для отправки личного сообщения:
<?php 
// Функция возвращает html формы для отправки личного сообщения 
function getSendMsgForm() 
{ 
  // Незарегистрированный пользователь не может отправлять личные сообщения 
  if ( !isset( $_SESSION['user'] ) ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die();  
  } 
   
  $html = '<h1>Личные сообщения</h1>'."\n"; 
  $html = $html.getMessagesMenu();  
   
  $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 = ''; 

  if ( isset( $_SESSION['viewMessage'] ) and !empty( $_SESSION['viewMessage']['message'] ) ) { 
    $view = file_get_contents( './templates/previewMessage.html' ); 
    $view = str_replace( '{message}', print_page( $_SESSION['viewMessage']['message'] ), $view );  
    $html = $html.$view."\n"; 
    $toUser  = htmlspecialchars( $_SESSION['viewMessage']['toUser'] ); 
    $subject = htmlspecialchars( $_SESSION['viewMessage']['subject'] ); 
    $message = htmlspecialchars( $_SESSION['viewMessage']['message'] ); 
    unset( $_SESSION['viewMessage'] ); 
  } 
   
  $action = $_SERVER['PHP_SELF'].'?action=sendMessage'; 
  // Если при заполнении формы были допущены ошибки 
  if ( isset( $_SESSION['sendMessageForm'] ) ) { 
    $info = file_get_contents( './templates/infoMessage.html' ); 
    $info = str_replace( '{infoMessage}', $_SESSION['sendMessageForm']['error'], $info ); 
    $html = $html.$info."\n"; 
    $toUser  = htmlspecialchars( $_SESSION['sendMessageForm']['toUser'] ); 
    $subject = htmlspecialchars( $_SESSION['sendMessageForm']['subject'] ); 
    $message = htmlspecialchars( $_SESSION['sendMessageForm']['message'] ); 
    unset( $_SESSION['sendMessageForm'] ); 
  } 
   
  $tpl = file_get_contents( './templates/sendMessageForm.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; 
} 
?>

Обработчик формы — функция sendMessage():
<?php 
// Отправка личного сообщения (добавляем новую запись в таблицу БД TABLE_MESSAGES) 
function sendMessage() 
{ 
  // Незарегистрированный пользователь не может отправлять личные сообщения 
  if ( !isset( $_SESSION['user'] ) ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die();  
  } 
   
  // Если не переданы данные формы - функция вызвана по ошибке 
  if ( !isset( $_POST['toUser'] ) or 
       !isset( $_POST['subject'] ) or 
       !isset( $_POST['message'] ) ) 
  { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die(); 
  } 

  $msgLen = strlen( $_POST['message'] ); 
   
  // Обрезаем переменные до длины, указанной в параметре maxlength тега input 
  $toUser  = substr( $_POST['toUser'], 0, 30 ); 
  $subject = substr( $_POST['subject'], 0, 60 ); 
  $message = substr( $_POST['message'], 0, MAX_MESSAGE_LENGTH ); 
  // Обрезаем лишние пробелы 
  $toUser  = trim( $toUser ); 
  $subject = trim( $subject ); 
  $message = trim( $message ); 
   
  // Если пользователь хочет посмотреть на сообщение перед отправкой 
  if ( isset( $_POST['viewMessage'] ) )  
  { 
    $_SESSION['viewMessage'] = array(); 
    $_SESSION['viewMessage']['toUser'] = $toUser; 
    $_SESSION['viewMessage']['subject'] = $subject; 
    $_SESSION['viewMessage']['message'] = $message; 
    header( 'Location: '.$_SERVER['PHP_SELF'].'?action=sendMsgForm' ); 
    die(); 
  } 
   
  // Проверяем, заполнены ли обязательные поля 
  $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 ( $msgLen > MAX_MESSAGE_LENGTH )  
    $error = $error.'<li>длина сообщения больше '.MAX_MESSAGE_LENGTH.' символов</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 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, 'action=sendMsgForm' ); 
    } 
    if ( mysql_num_rows( $res ) == 0 )  
      $error = $error.'<li>пользователь с именем <strong>'.$to.'</strong> не зарегистрирован</li>'."\n";
    if ( (mysql_num_rows( $res ) == 1 ) and (mysql_result( $res, 0, 0 ) == $_SESSION['user']['id_author']) ) 
      $error = $error.'<li>нельзя послать сообщение самому себе</li>'."\n"; 
  } 
  // Если были допущены ошибки при заполнении формы -  
  // перенаправляем посетителя для исправления ошибок 
  if ( !empty( $error ) ) 
  { 
    $_SESSION['sendMessageForm'] = array(); 
    $_SESSION['sendMessageForm']['error'] = '<p class="errorMsg">При заполнениии формы были допущены ошибки:</p>'. 
    "\n".'<ul class="errorMsg">'."\n".$error.'</ul>'."\n"; 
    $_SESSION['sendMessageForm']['toUser'] = $toUser; 
    $_SESSION['sendMessageForm']['subject'] = $subject; 
    $_SESSION['sendMessageForm']['message'] = $message; 
    header( 'Location: '.$_SERVER['PHP_SELF'].'?action=sendMsgForm' ); 
    die(); 
  } 
   
  // Все поля заполнены правильно - "посылаем" сообщение   
  $to = mysql_result( $res, 0, 0 ); 
  $from = $_SESSION['user']['id_author']; 
   
  $query = "INSERT INTO ".TABLE_MESSAGES." 
            VALUES  
            (  
            NULL,  
            ".$to.",  
            ".$from.", 
            NOW(),             
            '".mysql_real_escape_string( $subject )."',  
            '".mysql_real_escape_string( $message )."', 
            0, 
            0             
            )"; 
  $res = mysql_query( $query ); 
  if ( !$res ) { 
    $msg = 'Произошла ошибка при отправке сообщения'; 
    $err = 'Ошибка при выполнении запроса: <br/>'. 
           $query.'<br/>'.mysql_errno().': '.mysql_error().'<br/>'. 
           '(Файл '. __FILE__ .', строка '. __LINE__ .')'; 
    return showErrorMessage( $msg, $err, true, 'action=showOutBox' ); 
  } 
   
  return showInfoMessage( 'Ваше сообщение успешно отправлено', 'action=showOutBox' ); 
} 
?>

Функция getInMsgBox() возвращает список личных сообщений в папке "Входящие":
<?php 
// Папка личных сообщений (входящие) 
function getInMsgBox() 
{ 
  if ( !isset( $_SESSION['user'] ) ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die(); 
  } 
  $html = '<h1>Личные сообщения (входящие)</h1>'."\n"; 
  $html = $html.getMessagesMenu();  
   
  $html = $html.'<table class="showTable">'."\n"; 
  $html = $html.'<tr>'."\n"; 
  $html = $html.'<th width="2%"> </th>'."\n"; 
  $html = $html.'<th width="15%">Отправитель</th>'."\n"; 
  $html = $html.'<th width="63%">Тема сообщения</th>'."\n"; 
  $html = $html.'<th width="15%">Дата</th>'."\n"; 
  $html = $html.'<th width="5%">Удл.</th>'."\n"; 
  $html = $html.'</tr>'."\n"; 
  // Запрос на выборку входящих сообщений 
   
  // id_rmv - это поле указывает на то, что это сообщение уже удалил 
  // один из пользователей. Т.е. сначала id_rmv=0, после того, как 
  // сообщение удалил один из пользователей, id_rmv=id_user. И только после 
  // того, как сообщение удалит второй пользователь, мы можем удалить 
  // запись в таблице БД TABLE_MESSAGES 
  $query = "SELECT a.id_msg, a.subject, a.from_user, a.sendtime, a.viewed, b.name 
            FROM ".TABLE_MESSAGES." a INNER JOIN ".TABLE_USERS." b 
            ON a.from_user=b.id_author 
            WHERE a.to_user=".$_SESSION['user']['id_author']." 
            AND id_rmv<>".$_SESSION['user']['id_author']." 
            ORDER BY sendtime DESC"; 
  $res = mysql_query( $query ); 
   
  while ( $msg = mysql_fetch_row( $res ) ) { 
    $html = $html.'<tr>'."\n"; 
    // Если сообщение еще не прочитано 
    if ( $msg[4] == 0 ) 
      $html = $html.'<td align="center" valign="middle"><img src="./images/folder_new.gif" width="19" 
              height="18" alt="" /></td>'; 
    else 
      $html = $html.'<td align="center" valign="middle"><img src="./images/folder.gif" width="19"  
              height="18" alt="" /></td>';       
    $html = $html.'<td>'.$msg[5].'</td>'."\n"; 
    $html = $html.'<td><a href="'.$_SERVER['PHP_SELF'].'?action=showMsg&idMsg='. 
            $msg[0].'">'.$msg[1].'</a></td>'."\n"; 
    $html = $html.'<td>'.$msg[3].'</td>'."\n"; 
    $html = $html.'<td align="center"><a href="'.$_SERVER['PHP_SELF']. 
            '?action=deleteMsg&idMsg='.$msg[0].'"><img src="./images/icon_delete.gif" 
            alt="Удалить" title="Удалить" border="0" /></a></td>'."\n"; 
    $html = $html.'</tr>'."\n";     
  } 
  if ( mysql_num_rows( $res ) == 0 ) { 
    $html = $html.'<tr>'."\n"; 
    $html = $html.'<td colspan="4">В этой папке нет сообщений</td>'."\n"; 
    $html = $html.'</tr>'."\n"; 
  } 
  $html = $html.'</table>'."\n"; 
   
  return $html; 
} 
?>

Функция getOutMsgBox() возвращает список личных сообщений в папке "Исходящие":
<?php 
// Папка личных сообщений (исходящие) 
function getOutMsgBox() 
{ 
  if ( !isset( $_SESSION['user'] ) ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die(); 
  } 
  $html = '<h1>Личные сообщения (исходящие)</h1>'."\n"; 
  $html = $html.getMessagesMenu();  
   
  $html = $html.'<table class="showTable">'."\n"; 
  $html = $html.'<tr>'."\n"; 
  $html = $html.'<th width="15%">Получатель</th>'."\n"; 
  $html = $html.'<th width="65%">Тема сообщения</th>'."\n"; 
  $html = $html.'<th width="15%">Дата</th>'."\n"; 
  $html = $html.'<th width="5%">Удл.</th>'."\n"; 
  $html = $html.'</tr>'."\n"; 
   
  // Запрос на выборку исходящих сообщений  
  // id_rmv - это поле указывает на то, что это сообщение уже удалил 
  // один из пользователей. Т.е. сначала id_rmv=0, после того, как 
  // сообщение удалил один из пользователей, id_rmv=id_user. И только после 
  // того, как сообщение удалит второй пользователь, мы можем удалить 
  // запись в таблице БД TABLE_MESSAGES 
  $query = "SELECT a.id_msg, a.subject, a.to_user, a.sendtime, b.name 
            FROM ".TABLE_MESSAGES." a INNER JOIN ".TABLE_USERS." b 
            ON a.to_user=b.id_author 
            WHERE a.from_user=".$_SESSION['user']['id_author']." 
            AND id_rmv<>".$_SESSION['user']['id_author']." 
            ORDER BY sendtime DESC"; 
  $res = mysql_query( $query ); 
   
  while ( $msg = mysql_fetch_row( $res ) ) { 
    $html = $html.'<tr>'."\n"; 
    $html = $html.'<td>'.$msg[4].'</td>'."\n"; 
    $html = $html.'<td><a href="'.$_SERVER['PHP_SELF'].'?action=showMsg&idMsg='. 
            $msg[0].'">'.$msg[1].'</a></td>'."\n"; 
    $html = $html.'<td>'.$msg[3].'</td>'."\n"; 
    $html = $html.'<td align="center"><a href="'.$_SERVER['PHP_SELF']. 
            '?action=deleteMsg&idMsg='.$msg[0].'"><img src="./images/icon_delete.gif" 
            alt="Удалить" title="Удалить" border="0" /></a></td>'."\n"; 
    $html = $html.'</tr>'."\n";     
  } 
  if ( mysql_num_rows( $res ) == 0 ) { 
    $html = $html.'<tr>'."\n"; 
    $html = $html.'<td colspan="4">В этой папке нет сообщений</td>'."\n"; 
    $html = $html.'</tr>'."\n"; 
  } 
  $html = $html.'</table>'."\n"; 
   
  return $html;          
} 
?>

Вспомогательная функция getMessagesMenu() возвращает html меню для раздела "Личные сообщения":
<?php 
function getMessagesMenu() 
{ 
  $html = '<table width="100%">'."\n"; 
  $html = $html.'<tr valign="middle">'."\n"; 
  $html = $html.'<td><img src="./images/msg_inbox.gif" alt="Входящие" title="Входящие" /></td>'."\n"; 
  $html = $html.'<td><a class="header" href="'.$_SERVER['PHP_SELF']. 
          '?action=showInBox">Входящие</a>  </td>'."\n"; 
  $html = $html.'<td><img src="./images/msg_outbox.gif" alt="Исходящие" title="Исходящие" /></td>'."\n";
  $html = $html.'<td><a class="header" href="'.$_SERVER['PHP_SELF']. 
          '?action=showOutBox">Исходящие</a></td>'."\n"; 
  $html = $html.'<td align="right" width="90%"><a href="'.$_SERVER['PHP_SELF']. 
          '?action=sendMsgForm"><img  
          src="./images/msg_newpost.gif" alt="Новое сообщение"  
          title="Новое сообщение" /></a></td>'."\n"; 
  $html = $html.'</tr>'."\n"; 
  $html = $html.'</table>'."\n"; 
   
  return $html; 
} 
?>

Для удаления личного сообщения надо вызвать функцию deleteMessage():
<?php 
// Функция удаляет личное сообщение; ID сообщения передается методом GET 
function deleteMessage() 
{ 
  if ( !isset( $_SESSION['user'] ) ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die(); 
  } 

  if ( !isset( $_GET['idMsg'] ) ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die(); 
  }  

  $idMsg = (int)$_GET['idMsg']; 
  if ( $idMsg < 1 ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die(); 
  } 

  // Далее мы должны выяснить, удаляется входящее или исходящее 
  // сообщение. Это нужно, чтобы сделать редирект на нужный ящик. 
  // В этом запросе дополнительное условие нужно для того, чтобы 
  // пользователь не смог удалить чужое сообщение, просто указав 
  // ID сообщения в адресной строке браузера 
  $query = "SELECT to_user, id_rmv  
            FROM ".TABLE_MESSAGES."  
            WHERE id_msg=".$idMsg." AND  
            (to_user=".$_SESSION['user']['id_author']." OR from_user=".$_SESSION['user']['id_author'].")"; 
  $res = mysql_query( $query ); 
  if ( mysql_num_rows( $res ) == 0 ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'].'?action=showInBox' ); 
    die(); 
  } 

  list ( $toUser, $id_rmv ) = mysql_fetch_row( $res ); 
  if ( $toUser == $_SESSION['user']['id_author'] ) 
    $redirect = 'action=showInBox'; 
  else 
    $redirect = 'action=showOutBox'; 
  // id_rmv - это поле указывает на то, что это сообщение уже удалил 
  // один из пользователей. Т.е. сначала id_rmv=0, после того, как 
  // сообщение удалил один из пользователей, id_rmv=id_user. И только после 
  // того, как сообщение удалит второй пользователь, мы можем удалить 
  // запись в таблице БД TABLE_MESSAGES 
  if ( $id_rmv == 0 )  
    $query = "UPDATE ".TABLE_MESSAGES." SET id_rmv=".$_SESSION['user']['id_author']." WHERE id_msg=".$idMsg; 
  else 
    $query = "DELETE FROM ".TABLE_MESSAGES." WHERE id_msg=".$idMsg; 
  $res = mysql_query( $query ); 
  if ( !$res ) { 
    $msg = 'Произошла ошибка при удалении сообщения'; 
    $err = 'Ошибка при выполнении запроса: <br/>'. 
           $query.'<br/>'.mysql_errno().': '.mysql_error().'<br/>'. 
           '(Файл '. __FILE__ .', строка '. __LINE__ .')'; 
    return showErrorMessage( $msg, $err, true, $redirect ); 
  } 
  return showInfoMessage( 'Сообщение успешно удалено', $redirect ); 
} 
?>

Функция getMessage() возвращает личное сообщение для просмотра пользователем:
<?php 
// Функция возвращает личное сообщение для просмотра пользователем 
function getMessage() 
{ 
  if ( !isset( $_SESSION['user'] ) ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die(); 
  } 
  if ( !isset( $_GET['idMsg'] ) ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'] ); 
    die(); 
  } 
  $idMsg = (int)$_GET['idMsg']; 
  if ( $idMsg < 1 ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'].'?action=showInBox' ); 
    die(); 
  } 
  // Получаем из БД информацию о сообщении. 
  // В этом запросе дополнительное условие нужно для того, чтобы 
  // пользователь не смог просмотреть чужое сообщение, просто указав 
  // ID сообщения в адресной строке браузера 
  $query = "SELECT a.to_user, a.from_user, a.subject, a.sendtime, a.message, a.viewed, 
                   b.name AS to_user_name, c.name AS from_user_name   
            FROM ".TABLE_MESSAGES." a INNER JOIN ".TABLE_USERS." b 
            ON a.to_user=b.id_author 
            INNER JOIN ".TABLE_USERS." c 
            ON a.from_user=c.id_author 
            WHERE id_msg=".$idMsg."  
            AND (a.to_user=".$_SESSION['user']['id_author']." OR a.from_user=".$_SESSION['user']['id_author'].") 
            AND a.id_rmv<>".$_SESSION['user']['id_author']; 
  $res = mysql_query( $query ); 
  if ( !$res ) { 
    $msg = 'Произошла ошибка при получении сообщения'; 
    $err = 'Ошибка при выполнении запроса: <br/>'. 
           $query.'<br/>'.mysql_errno().': '.mysql_error().'<br/>'. 
           '(Файл '. __FILE__ .', строка '. __LINE__ .')'; 
    return showErrorMessage( $msg, $err, true, 'action=showInBox' ); 
  } 
  if ( mysql_num_rows( $res ) == 0 ) { 
    header( 'Location: '.$_SERVER['PHP_SELF'].'?action=showInBox' ); 
    die(); 
  } 
  // Далее мы должны выяснить, запрашивается входящее или исходящее 
  // сообщение? Это нужно, чтобы правильно указать "Отправитель" 
  // или "Получатель" и вывести заголовок страницы: "Входящие"  
  // или "Исходящие" 
  $message = mysql_fetch_array( $res ); 
  if ( $message['to_user'] == $_SESSION['user']['id_author'] ) { 
    $redirect = 'action=showInBox'; 
    $inBox = true; 
  } else { 
    $redirect = 'action=showOutBox'; 
    $inBox = false; 
  } 
  // Формируем заголовок страницы 
  if ( $inBox )  // Папка "Входящие" 
    $html = '<h1>Личные сообщения (входящие)</h1>'."\n"; 
  else           // Папка "Исходящие" 
    $html = '<h1>Личные сообщения (исходящие)</h1>'."\n"; 
  $html = $html.getMessagesMenu(); 
  $html = $html.'<table class="showTable">'."\n"; 
  $html = $html.'<tr>'."\n"; 
  $html = $html.'<th colspan="2">Сообщение</th>'."\n"; 
  $html = $html.'</tr>'."\n"; 
  $html = $html.'<tr>'."\n"; 
  if ( $inBox ) { 
    $html = $html.'<td width="15%">Отправитель</td>'."\n"; 
    $html = $html.'<td width="85%">'.$message['from_user_name'].'</td>'."\n"; 
  } else { 
    $html = $html.'<td width="15%">Получатель</td>'."\n"; 
    $html = $html.'<td width="85%">'.$message['to_user_name'].'</td>'."\n"; 
  } 
  $html = $html.'</tr>'."\n"; 
  $html = $html.'<tr>'."\n"; 
  if ( $inBox ) 
    $html = $html.'<td>Отправлено</td>'."\n"; 
  else 
    $html = $html.'<td>Получено</td>'."\n"; 
  $html = $html.'<td>'.$message['sendtime'].'</td>'."\n"; 
  $html = $html.'<tr>'."\n"; 
  $html = $html.'</tr>'."\n"; 
  $html = $html.'<td>Тема</td>'."\n"; 
  $html = $html.'<td>'.$message['subject'].'</td>'."\n"; 
  $html = $html.'<tr>'."\n"; 
  $html = $html.'</tr>'."\n"; 
  $html = $html.'<td>Сообщение</td>'."\n"; 
  $html = $html.'<td>'.print_page( $message['message'] ).'</td>'."\n"; 
  $html = $html.'</tr>'."\n"; 
  $html = $html.'</table>'."\n"; 
   
  // Помечаем сообщение, как прочитанное 
  if ( $inBox and $message['viewed'] != 1 ) { 
    $query = "UPDATE ".TABLE_MESSAGES." SET viewed=1 WHERE id_msg=".$idMsg; 
    mysql_query( $query ); 
  } 
   
  return $html; 
} 
?>

Продолжение следует...
Теги:
форум
Добавлено: 22 Сентября 2013 01:33:28 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...