Advertisement
Guest User

Гостевая книга

a guest
Jun 3rd, 2016
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 20.63 KB | None | 0 0
  1. <?php
  2.     $messages_per_page = 5; #Параметр, определяющий число отображаемых на странице сообщений
  3.    
  4.     #Цикл инициализации основных переменных
  5.    foreach (array('username', 'password', 'login_action', 'login_error', 'message_action', 'message_error', 'message', 'current_page', 'delete_message') as $variable_name) {
  6.         $$variable_name = isset($_REQUEST[$variable_name])
  7.                         ? $_REQUEST[$variable_name]
  8.                         : '';
  9.     }
  10.     $password = md5($password); #Сразу взять хэш от пароля
  11.    
  12.     #Если текущая страница пользователя еще не установлена, то установить ее первой страницей
  13.    if (!isset($_COOKIE['current_page']))
  14.         set_cookie_now('current_page', 1);
  15.    
  16.     #Если была указана текущая страница, то установать ее
  17.    if ($current_page !== '')
  18.         set_cookie_now('current_page', $current_page);
  19.    
  20.     #Если была нажата кнопка, связанная с логином
  21.    if ($login_action !== '') {
  22.         #Если пользователь нажал кнопку "Выйти", то установить соответствующий флаг равным false и удалить имя пользователя из COOKIE
  23.        if ($login_action == 'Выйти') {
  24.             $is_logged = false;
  25.             unset_cookie_now('username');
  26.         }
  27.         #Иначе выполнить авторизацию
  28.        else
  29.             $login_error = log_user_in($username, $password, $login_action === 'Зарегестрироваться');
  30.     }
  31.    
  32.     $is_logged = isset($_COOKIE['username']); #Флаг, отражающий, вошел пользователь на сайт или нет
  33.  
  34.     #Если была нажата кнопка отправки сообщения
  35.    if ($message_action == 'Отправить') {
  36.         #Если пользователь авторизировался, забрать его имя из COOKIE
  37.        if ($is_logged)
  38.             $username = $_COOKIE['username'];
  39.        
  40.         #Если имя пользователя или сообщение пустые, то вывести ошибку
  41.     if ($username == '' || $message == '')
  42.             $message_error = 'Вы должны ввести свое имя и текст сообщения!';
  43.        
  44.         #Если все данные корректны
  45.        if ($message_error === '') {
  46.             #Загрузить сообщения и взять последнее
  47.            $messages = load_from_file('messages.txt');
  48.             $last_message = end($messages);
  49.            
  50.             #Если последнего сообщения нет (еще никто не отправлял сообщений)
  51.            #То установать номер предыдущего сообщения равным нулю
  52.            #Иначе взять номер предыдущего сообщения
  53.            $last_message_number = $last_message === false
  54.                     ? 0
  55.                     : $last_message[0];
  56.        
  57.             #Сформировать новое сообщение как массив вида: номер сообщения, имя пользователя, дата, текст сообщения, адрес отправителя, а затем сохранить его
  58.            $new_message = array($last_message_number + 1, $username, date('j M o H:i:s'), $message, $_SERVER['REMOTE_ADDR']);
  59.             save_to_file('messages.txt', $new_message);
  60.         }
  61.     }  
  62.    
  63.     #Если была нажата кнопка удаления сообщения
  64.    if ($delete_message !== '') {
  65.         $messages = load_from_file('messages.txt'); #Загрузить все сообщения
  66.        
  67.         #Пройтись по всем сообщениям
  68.        foreach ($messages as $key=>$message) {
  69.             #Если номер удаляемого сообщения совпадает с номером текущего сообщения, то удалить это сообщение и выйти из цикла
  70.            if ($message[0] === $delete_message) {
  71.                 unset($messages[$key]);
  72.                 break;
  73.             }
  74.         }
  75.        
  76.         #Удалить файл с сообщениями, если он был
  77.        if (is_file('messages.txt'))
  78.             unlink('messages.txt');
  79.        
  80.         #Сохранить каждое сообщение
  81.        foreach ($messages as $message)
  82.             save_to_file('messages.txt', $message);
  83.     }
  84.    
  85.     print create_header()
  86.             .create_login_form($is_logged, $login_error)
  87.             .create_message_box($is_logged, $message_error)
  88.             .create_message_viewer($messages_per_page, $_COOKIE['current_page'], $is_logged);
  89.    
  90.     /**
  91.      * Авторизация пользователя
  92.      * @param string $__username   - имя пользователя
  93.      * @param string $__password   - md5 хэш пароля пользователя
  94.      * @param bool   $__is_sign_up - осуществляет ли пользователь регистрацию
  95.      * @return string               - описание случившейся ошибки
  96.      */
  97.     function log_user_in($__username, $__password, $__is_sign_up) {
  98.         #Если имя пользователя или пароль не были введены
  99.        if ($__username === '' || $__password === md5(''))
  100.             return 'Вы не можете оставлять поля пустыми!';
  101.        
  102.         #Загрузить пользователей из файла
  103.        $users = load_from_file('users.txt');
  104.        
  105.         #Инициализировать переменные
  106.        $does_user_exist = false;
  107.         $user_password = '';
  108.        
  109.         #Пройти по каждому пользователю
  110.        foreach($users as $user) {
  111.             #Если введенное имя пользователя совпадает с именем уже существующего пользователя, то установить флаг существования пользователя, сохранить его пароль и выйти из цикла
  112.            if ($user[0] === $__username) {
  113.                 $does_user_exist = true;
  114.                 $user_password = $user[1];
  115.                 break;
  116.             }
  117.         }
  118.        
  119.         #Если осуществляется регистрация
  120.        if ($__is_sign_up) {
  121.             #Если пользователь уже существует, то вернуть ошибку
  122.            if ($does_user_exist)
  123.                 return 'Пользователь с таким именем уже существует!';
  124.            
  125.             #Иначе создать нового пользователя как массив вида: имя пользователя, пароль, а затем сохранить его
  126.            $new_user = array($__username, $__password);
  127.             save_to_file('users.txt', $new_user);
  128.         }
  129.         #Если осуществляется вход
  130.        else {
  131.             #Если пользователь не существует или пароль был введен неверно, то вернуть ошибку
  132.            if (!$does_user_exist || $user_password !== $__password)
  133.                 return 'Неверное имя пользователя или пароль!';
  134.         }            
  135.        
  136.         #Установить соответствующее куки
  137.        set_cookie_now('username', $__username);
  138.     }
  139.    
  140.     /**
  141.      * Создает заголовок сайта
  142.      * @return string - заголовок сайта
  143.      */
  144.     function create_header() {
  145.         return '<head>'
  146.             .'<meta http-equiv="content-type" content="text/html; charset=utf-8">'
  147.             .'<link rel="stylesheet" href="style.css"/>'
  148.             .'</head>';
  149.     }
  150.    
  151.     /**
  152.      * Создает форму авторизации
  153.      * @param bool $__is_logged     - флаг, определяющий, авторизирован ли пользователь
  154.      * @paran string $__login_error - ошибка при авторизации пользователя
  155.      * @return string               - форма авторизации
  156.      */
  157.     function create_login_form($__is_logged, $__login_error) {
  158.         return $__is_logged
  159.                ? '<form class="auth" action="" method="get">
  160.                    Hello, '.$_COOKIE['username'].'!
  161.                    <input class="button" type="submit" name="login_action" value="Выйти"/><br>
  162.                  </form>'
  163.                : '<form class="auth" action="" method="get">
  164.                    <p><input class="username" type="text" name="username" value="" placeholder="имя пользователя"/>
  165.                    <input class="password" type="password" name="password" value="" placeholder="пароль"/></p>
  166.                    <p><input class="button" type="submit" name="login_action" value="Войти"/>
  167.                    <input class="button" type="submit" name="login_action" value="Зарегестрироваться"/></p>'.
  168.                     ($__login_error == '' ? '' : '<span class="error">'.$__login_error.'</span>'). #Если была ошибка, то необходимо ее вывести
  169.                 '</form>';
  170.     }
  171.    
  172.     /**
  173.      * Создает форму отправки сообщения
  174.      * @param bool   $__is_logged     - флаг, определяющий, авторизирован ли пользователь
  175.      * @param string $__message_error - ошибка при отправке сообщения
  176.      * @return string                 - форма отправки сообщения
  177.      */
  178.     function create_message_box($__is_logged, $__message_error) {
  179.         return '<form class="message_sender" action="" method="get">'
  180.                     . ($__is_logged ? '' : '<p><input class="username" type="text" name="username" value="" placeholder="имя пользователя"/> :</p>') #Если пользователь не был авторизирован, то оставить поле ввода, иначе не отображать его
  181.                    . '<p><input class="message_box" type="text" name="message" value="" placeholder="сообщение"/>
  182.                    <input class="button" type="submit" name="message_action" value="Отправить"/></p>'.
  183.                     ($__message_error == '' ? '' : '<span class="error">'.$__message_error.'</span>'). #Если была ошибка, то необходимо ее вывести
  184.            '</form>';
  185.     }
  186.    
  187.     /**
  188.      * Создает механизм отображения сообщений
  189.      * @param int  $__messages_per_page - количество сообщений на страницу
  190.      * @param int  $__current_page      - текущая страница
  191.      * @param bool $__is_logged         - флаг, определяющий, авторизирован ли пользователь
  192.      * @return string                   - механизм отображения сообщений
  193.      */
  194.     function create_message_viewer($__messages_per_page, $__current_page, $__is_logged) {
  195.         $messages = array_reverse(load_from_file('messages.txt')); #Загрузить массив сообщений и реверсировать его для правильного отображения
  196.        $number_of_pages = ceil(count($messages) / $__messages_per_page); #Получить число страниц как округленный вверх результат деления числа сообщений на количество сообщений на страницу
  197.        
  198.         #Если текущая страница за пределами числа страниц, установить стандартное значение
  199.        if ($__current_page > $number_of_pages)
  200.             $__current_page = 1;
  201.        
  202.         $result = ''; #Результат работы функции
  203.        $messages_to_print = array_slice($messages, $__messages_per_page * ($__current_page - 1), $__messages_per_page); #Взять те сообщения, которые будут сейчас отображены на экране
  204.        
  205.         #Проход по всем отображаемым сообщениям
  206.        foreach ($messages_to_print as $message) {
  207.             $result .= '<p><div class="message">'
  208.                     . '<span class=message_header>'
  209.                     . '<span class=name><b>'.$message[1].'</b></span>' #Напечатать имя
  210.                    . '<span class=extra>'.$message[2].' ' #Напечатать время
  211.                    #Если пользователь авторизирован как администратор, то вывести ip адрес и кнопку удаления сообщения, иначе не выводить ничего
  212.                    . ($__is_logged && $_COOKIE['username'] === 'admin'
  213.                         ? '&nbsp;&nbsp;&nbsp;&nbsp;'.$message[4]."&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"index.php?delete_message=".$message[0]."\"><img class=delete src=\"delete_icon.ico\" alt=\"\"></a>"  
  214.                         : '').'</span>'
  215.                     . '</span>'
  216.                     . '<p class="message_text">'.$message[3].'</p>' #Вывести текст сообщения
  217.                    . '</div></p>';
  218.         }
  219.        
  220.         $result .= '<div class="navigator"><p>'; #Добавить блок навигатора по страницам
  221.        
  222.         #Если число страниц меньше четырех, то необходимо вывести номера всех страниц подряд
  223.        if ($number_of_pages < 4) {
  224.             #Пройти по каждому индексу страницы
  225.            for ($page_index = 1; $page_index <= $number_of_pages; ++$page_index)
  226.                 #Если индекс страницы совпал с номером текущей страницы, то напечатать подчеркнутый текст, иначе создать ссылку на страницу
  227.                $result .= $page_index == $__current_page
  228.                     ? ' <u>'.$page_index.'</u> '
  229.                     : " <a href=\"index.php?current_page=$page_index\"><b>$page_index</b></a> ";
  230.         }
  231.         #Иначе сделать навигатор красивым и функциональным (со стрелочками)
  232.        else
  233.             #В зависимости от текущей страницы
  234.            switch($__current_page)
  235.             {
  236.                 case 1: #Первая страница
  237.                    $result .= "<u>$__current_page</u> " #Вывести номер страницы
  238.                            .  "<a href=\"index.php?current_page=2\"><b>></b></a>" #Сделать стрелку вправо (ссылка на вторую страницу)
  239.                            .  " ... ... ... " #Декорация
  240.                            .  "<a href=\"index.php?current_page=$number_of_pages\"><b>$number_of_pages</b></a></p></div>"; #Сделать ссылку на последнюю страницу
  241.                    break;
  242.                 case $number_of_pages: #Последняя страница
  243.                    $result .= "<a href=\"index.php?current_page=1\"><b>1</b></a>" #Сделать ссылку на первую страницу
  244.                            .  " ... ... ... " #Декорация
  245.                            .  "<a href=\"index.php?current_page=".($number_of_pages - 1)."\"><b><</b></a> " #Сделать стрелку влево (ссылка на предпоследнюю страницу)
  246.                            .  "<u>$__current_page</u></p></div>"; #Вывести номер страницы
  247.                    break;
  248.                 default: #Любая другая страница
  249.                    $result .= "<a href=\"index.php?current_page=1\"><b>1</b></a>" #Сделать ссылку на первую страницу
  250.                            .  " ... " #Декорация
  251.                            .  "<a href=\"index.php?current_page=".($__current_page - 1)."\"><b><</b></a> " #Сделать стрелку влево (ссылка на предыдущую страницу)
  252.                            .  " <u>$__current_page</u> " #Вывести номер страницы
  253.                            .  "<a href=\"index.php?current_page=".($__current_page + 1)."\"><b>></b></a> " #Сделать стрелку вправо (ссылка на следующую страницу)
  254.                            .  " ... " #Декорация
  255.                            .  "<a href=\"index.php?current_page=$number_of_pages\"><b>$number_of_pages</b></a></p></div>"; #Сделать ссылку на последнюю страницу
  256.            }
  257.        
  258.         return $result;
  259.     }
  260.    
  261.     /**
  262.      * Функция, сохраняющая массив в указанный файл
  263.      * @param type $__filename - файл, в который произвести сохранение
  264.      * @param type $__array    - массив, который необходимо сохранить
  265.      */
  266.     function save_to_file($__filename, $__array) {
  267.         $result = ''; #Инициализировать результат
  268.        
  269.         #Если файла не существует, то создать его и добавить открывающий баян
  270.        if (!is_file($__filename)) {
  271.             touch($__filename);
  272.             $result .= '[:|||:]';
  273.         }
  274.  
  275.         #Проход по всем элементам массива и добавление к результату соответствующего поля
  276.        foreach($__array as $elem)
  277.             $result .= $elem
  278.                 #Если обрабатываем последний элемент массива, то поставить закрывающий баян, иначе разделительный
  279.                .($elem == end($__array)
  280.                 ? '[:|||:]'
  281.                 : '[:||:]');
  282.        
  283.         file_put_contents($__filename, $result, FILE_APPEND); #Дописать получившуюся строку в файл
  284.    }
  285.    
  286.     /**
  287.      * Функция, загружающая из файла массив данных
  288.      * @param string $__filename - файл, из которого необходимо прочитать массив данных
  289.      * @return array             - массив данных
  290.      */
  291.     function load_from_file($__filename) {
  292.         #Если указанного файла не существует, то вернуть пустой массив
  293.        if (!is_file($__filename))
  294.             return array();
  295.        
  296.         #Прочитать данные из файла и разделить по большим баянам
  297.        $data = file_get_contents($__filename);
  298.         $splitted_data = explode('[:|||:]', $data);
  299.        
  300.         $result = array(); #Инициализировать результат пустым массивом
  301.        
  302.         #Проход по каждому блоку данных
  303.        foreach ($splitted_data as $data) {
  304.             #Если блок данных не пустой, то разделить его по маленьким баянам и добавить в результат
  305.            if ($data !== '')
  306.                 $result[] = explode('[:||:]', $data);
  307.         }
  308.        
  309.         return $result;
  310.     }
  311.    
  312.     /**
  313.      * Сохраняет куки на 30 минут и позволяет работать этим значением сразу же
  314.      * @param string $__key  - ключ
  315.      * @param mixed $__value - значение
  316.      */
  317.     function set_cookie_now($__key, $__value) {
  318.         setcookie($__key, $__value, time() + 60 * 30);
  319.         $_COOKIE[$__key] = $__value;
  320.     }
  321.    
  322.     /**
  323.      * Удалить куки прямо сейчас
  324.      * @param string $__key - ключ
  325.      */
  326.     function unset_cookie_now($__key) {
  327.         setcookie($__key, '', 1);
  328.         unset($_COOKIE[$__key]);
  329.     }
  330. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement