Если вы следите за новыми web сервисами, то наверняка слышали о системе Orphus Дмитрия Котерова. Её основная цель – уменьшить количество орфографических ошибок на web сайтах.
Идея очень простая и элегантная. Если посетитель видит ошибку, то он выделяет её с помощью мышки и нажимает «Ctrl+Enter». После этого, владелец сайта получает письмо с выделенным текстом. Главное преимущество в том, что посетителю нужно сделать минимум действий. Никаких перезагрузок страниц и заполнения форм, нужна только поддержка JavaScript в браузере.
В этой статье я расскажу о том, как самостоятельно сделать подобную систему для собственного сайта.
Преимущества такого решения.
1) Вы не зависите от стороннего сервиса.
2) Сообщения об опечатках можно будет просматривать через web интерфейс. Все-таки это удобнее чем копаться в почте 😉 .
3) Можно легко реализовать защиту от спама.
Итак, приступаем.
Наша система будет состоять из трёх компонентов:
1) html страница со JavaScript функцией, которая будет отправлять сообщение (AJAX-запрос);
2) PHP скрипт, добавляющий сообщение в базу данных;
3) PHP скрипт для просмотра сообщений.
Такую простую структуру я выбрал специально, т.к. по большому счету эта система должна быть интегрирована в движок сайта, а их очень много. Привязываться к отдельному решению мне не хотелось.
Рассмотрим главную страницу.
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Ctrl Space Sender</title><link rel="stylesheet" href="css/blueprint/screen.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="css/blueprint/print.css" type="text/css" media="print" /> <!--[if IE]><link rel="stylesheet" href="css/blueprint/ie.css" type="text/css" media="screen, projection" /><![endif]--> <script type="text/javascript" src="js/jquery/jquery-1.2.3.js"></script> <script type="text/javascript"> $(document).ready( function() { //назначаем обработчик нажатия на Ctrl + Enter $(document).keypress( function(e) { //если посетитель нажал Ctrl + Enter... if ((e.ctrlKey == true) && (e.keyCode == 13)) { //...ищем выделенный текст... var selectedText = window.getSelection(); //...и отправляем запрос $.ajax({ type: "POST", url: "errorscollector.php", data: {text:[selectedText], pageurl:[window.location.href]}, success: function(msg) { alert(msg); } }); } } ); } ); </script> </head> <body> <h1>Привет</h1> <p>Эта тестовая страница выполняет обработку нажатия на клавиши....</p> </body> </html>
Наибольший интерес здесь представляет скрипт обработки нажатий на клавиши (строки 13-37). Чтобы немного сократить его код я использовал библиотеку jQuery (строка 12).
Разберем его подробнее.
С помощью функции ready
указываем, что наш код должен выполняться только после полной загрузки страницы.
Функция keypress
назначает обработчик, который будет вызываться при нажатии на любую клавишу. В нашем случае этим обработчиком является анонимная функция (строки 18-33).
Примечание. Вы можете назначить обработчик любому блоку на странице. Для этого с помощью функции $(...)
укажите нужный блок.
В первом параметре наша функция получает объект с данными о возникшем событии (в данном случае это нажатие на клавишу).
Код нажатой клавиши содержится в свойстве keyCode
этого объекта. Кроме того, если свойство ctrlKey
указывает на то, была ли нажата клавиша «Ctrl» (ctrlKey == true
). Аналогичное назначение имеет свойство altKey
(устанавливается в true
, если нажата клавиша «Alt»).
Т.е. мы проверяем, была ли нажата комбинация клавиш «Ctrl+Enter» и если да, то с помощью window.getSelection()
получаем выделенный текст и отправляем AJAX запрос.
В параметре url
указываем название PHP скрипта, который добавляет данные об опечатке в базу, а в параметре data
– выделенный текст и адрес страницы.
После получения ответа от сервера будет вызвана функция, указанная в параметре success
(строки 28-30). Она просто покажет сообщение сервера посетителю.
Таблица, в которой будут храниться сообщения, называется errorsdata и имеет 5 полей:
1) id
– первичный ключ;
2) addtime
– время добавления сообщения;
3) errmes
– текст сообщения;
4) userip
– IP адрес посетителя;
5) pageUrl
– адрес страницы, на которой была найдена ошибка.
Теперь рассмотрим PHP скрипт, сохраняющий сообщения в базе данных.
<?php try { //получаем IP посетителя $userIp = $_SERVER['REMOTE_ADDR']; $con = new PDO('mysql:host=localhost;dbname=databaseName', 'userName', 'password'); $stm = $con->prepare('SELECT id FROM errorsdata WHERE userip=:ip AND addtime > DATE_SUB(NOW(), INTERVAL 1 HOUR)'); $stm->execute(array('ip'=>$userIp)); $res = $stm->fetchAll(PDO::FETCH_ASSOC); if (count($res) < 3) { $qIns = $con->prepare('INSERT INTO errorsdata (errmes, userip, pageUrl) VALUES (:mes, :ip, :url)'); $qIns->execute(array('mes'=>$_POST['text'], 'ip'=>$userIp, 'url'=>$_POST['pageurl'])); if ($qIns->rowCount() == 1) { echo "Ваше сообщение получено"; } } else { echo "Вы отправляете слишком много сообщений. Пожалейте администратора!"; } } catch (PDOException $e) { echo 'Не могу подключиться к БД'; } ?>
Принцип работы следующий.
Сначала мы проверяем сколько запросов в течении последнего часа отправил данный посетитель. Для этого мы получаем из базы все записи, с данным IP и добавленные не ранее часа назад (строки 7-9).
Если таких записей меньше 3-х – добавляем сообщение в базу (строки 10-16).
В противном случае – игнорируем запрос.
Примечание. В данном примере для работы с базой я использовал PDO, если вы встраиваете эту систему в какой-то фреймворк, то удобнее будет использовать его библиотеку для работы с БД.
Как видите, скрипт возвратит обычную текстовую строку, которая и будет показана посетителю (строка 29 первого листинга).
Теперь напишем скрипт для просмотра сообщений.
Предупреждаю сразу. Прежде чем использовать его в реальном приложении, необходимо добавить авторизацию.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru"> <head> <title>Сообщения об ошибках</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <link rel="stylesheet" href="css/blueprint/screen.css" type="text/css" media="screen, projection" /> <link rel="stylesheet" href="css/blueprint/print.css" type="text/css" media="print" /> <!--[if IE]><link rel="stylesheet" href="css/blueprint/ie.css" type="text/css" media="screen, projection" /><![endif]--> </head> <body> <?php try { $con = new PDO('mysql:host=localhost;dbname=databaseName', 'userName', 'password'); $stm = $con->prepare('SELECT id, addtime, errmes, pageUrl FROM errorsdata'); $stm->execute(); $res = $stm->fetchAll(PDO::FETCH_ASSOC); if (count($res) == 0) { echo "Сообщения отсутствуют"; } else { echo "<table summary=\"Эта таблица содержит сообщения об ошибках\">"; echo "<caption>Сообщения об ошибках</caption>"; echo "<tr>"; echo "<th>#</th>"; echo "<th>Текст с ошибкой</th>"; echo "<th>Дата</th>"; echo "<th>URL страницы</th>"; echo "</tr>"; $i = 0; foreach ($res as $row) { if ($i % 2 == 0) { echo "<tr>"; } else { echo "<tr class=\"even\">"; } echo "<td>".$row['id']."</td>"; echo "<td>".$row['errmes']."</td>"; echo "<td>".$row['addtime']."</td>"; echo "<td><a href=\"".$row['pageUrl']."\">".$row['pageUrl']."</a></td>"; echo "</tr>"; $i++; } echo "</table>"; } } catch (PDOException $e) { echo '<h1>Не могу подключиться к БД</h1>'; } ?> </body> </html>
По большому счету тут и комментировать нечего. Основную часть занимает обычная html разметка.
Мы выполняем всего один запрос (строки 20-22), с помощью которого получаем данные из базы.
После этого в цикле добавляем эти данные в html таблицу.
Кстати, чтобы не писать стили самому я использовал CSS фреймворк Blueprint. Раньше я с ним практически не работал, но, похоже, вещь довольно удобная.
Скачать
Вы можете скачать архив со скриптом. Для того чтобы запустить пример вам нужно:
1) включить поддержку PDO (в php.ini);
2) создать базу данных;
3) создать таблицу для хранения сообщений (запрос, создающий таблицу находится в файле dump.sql);
4) указать параметры подключения к базе в файлах viewer.php и errorscollector.php.
Как видите, с помощью нескольких десятков строк кода мы создали довольно удобную систему отправки сообщений. Если у вас возникли вопросы или замечания – пишите, постараюсь ответить 😉 .
UPD (27.12.2008): Внимание! Скрипт, приведенный в статье, работает только в FireFox и Opera. Кроссбраузерный вариант приведен в комментариях (тестировался в FireFox, Opera, IE и Chrome).
Интересно почитать:
Простая техника для настройки MFA сайтов и для улучшения QS на лендинг страницах.