http://blagtalkan.ru
http://oktpoisk.ru
http://mysorru.ru/
http://san-okt.ru/
http://pes6evolution.ru/
http://chasikigov.ru
http://serafimsovet.ru
http://filmsgov.ru
http://free-domen.ru
http://fithonda.ru/forums/index.php
http://avtogov.ru
http://www.1001bilet.com.ua/base/on-line/
http://pravilavoini.ru
http://school41ufa.ru
http://rusrav4.ru
Получение электронной почты | Книга AJAX
 

Получение электронной почты с сервера РОРЗ не самая проста» ча, а ее описание далеко выходит за рамки данной книги. По данном примере для ее решения мы задействуем библиотеку ] Она содержит большое количество классов, предназначенных, ганизации взаимодействий такого типа. Эти классы понадобятся] ду checkMailO, отвечающему за получение почтовых сс с сервера РОРЗ и сохранение их в базе данных.
Метод начинается с создания нового экземпляра класса РорЗ, го класса в библиотеке POP3Lib, призванного обеспечивать действие с сервером РОРЗ. Конструктор класса принимает че гумента, три из которых задавать обязательно. Первый аргумент сетевое имя сервера РОРЗ, второй - имя пользователя, третий-роль пользователя, а четвертый (необязательный) - номер по единения с сервером РОРЗ (по умолчанию 110). Соединение с < открывается с помощью метода login(). Этот метод возвращает: ское значение, определяющее успешное (true) или неудачное (fall единение:
class AjaxMailbox {
// методы работы с базой данных
function checkMailO {
$рор = new Pop3(P0P3_SERVER, P0P3_USER, P0P3_PASSW0R0);
if ($pop->login()) {
// здесь находится код получения сообщений . // и сохранения их в базе данных.

Метод checkMail() начинается с создания экземпляра класса РорЗ с ис¬пользованием констант, определенных в файле condig. inc. php. Затем вызывается метод login(), который пытается установить соединение с сервером.
В случае успешного соединения с сервером объект класса РорЗ получает число сообщений на сервере и записывает его в свойство mailCount. До¬полнительно инициализируется массив messages, который затем запол¬няется заголовками сообщений, находящимися на сервере (заголовок содержит информацию о том, кому и кем было послано сообщение, тему сообщения, дату и признак наличия вложений). Каждый элемент мас¬сива messages представляет собой ссылку на объект класса Pop3Header.
Чтобы получить электронную почту целиком, с заголовками, собствен¬но сообщениями и вложениями, необходимо вызвать метод getEmails(). Этот метод полностью переписывает содержимое массива messages, за¬полняя его ссылками на объекты класса Pop3Message, которые, в свою очередь, содержат полную информацию о почтовых отправлениях. Объ¬екты класса Pop3Message обладают следующими методами и свойствами:
Эти свойства и методы нужны для извлечения информации о i вых отправлениях и записи ее в базу данных.
В случае успешного соединения с сервером прежде всего не проверить наличие сообщений на нем. Это можно сделать с свойства mailCount. Если его значение больше нуля, то для по почты вызывается метод getEmails(), и перед записью новых < ний в базу выполняется соединение с базой данных :
class AjaxMailbox {
// методы работы с базой данных
function checkMailO {
$рор = new Pop3(P0P3_SERVER, P0P3JJSER, P0P3_PASSWORD);
if ($pop->login()) {
if ($pop->mailCount >0) {
$conn = $this->connect(); $pop->getEmailsO; // здесь находится остальной код $this->disconnect($conn);

$pop->logoff();

>
// здесь находится остальной код
}
В этом отрывке кода в соответствующих точках показаны ме connect () и logoff (). Метод logoff (), как вы уже наверняка дот закрывает соединение с сервером РОРЗ.
После того как новые почтовые сообщения будут получены с < их можно записать в базу данных, обойдя в цикле все сообщев сиве messages:
class AjaxMailbox {
// методы работы с базой данных
function checkMailO {
$рор = new Pop3(P0P3_SERVER, P0P3_USER, P0P3_PASSW0R0);
if ($pop->login()) {
if ($pop->mailCount > 0) {
$conn = $this->connect(); $pop->getEmails();
foreach ($pop->messages as $message) { $query = "insert into AjaxMailMessages(-To',CC,BCC2 $query .=
"Subject,'Date",Message,HasAttachments,Folderld.

$query .= " values('%s','%s','%s','4s*,'%s',%s,'%s'," .$message->hasAttachments.",1,1)"; ,v Squery =:sprintf(Squery,
(addslashes($message->to)), (addslashes($message->cc)), (addslashes($message->bcc)), (addslashes($message->from)), (addslashes($message->subject)), , $message->unixTimeStamp,
(addslashes($message->getTextMessage()))
);
$result = mysql_query($query, $conn); //здесь находится остальной код
Ф'М'"(ЖЩ^^: :>Ш* $this->disconnect($conn);

}
$pop->logoff();

>
// здесь находится остальной код
}
Для обхода массива с сообщениями организован цикл f о reach. Для каж¬дого сообщения создается и исполняется SQL-оператор INSERT. Предло¬жение SQL достаточно длинное, поэтому оно создается с помощью функции sprintf (). Обратите внимание, что каждое из значений (за ис¬ключением unixTimeStamp) должно быть преобразовано с помощью функции addslashes(), чтобы их можно было вставлять в текст SQL^a-проса. Исполнение запроса осуществляет функция mysql_query(). Оста¬лось лишь обработать вложения.
Определить наличие вложения можно с помощью свойства hasAttach-ments. Если почтовое сообщение сопровождается вложениями, то сна¬чала необходимо определить идентификатор последнего сообщения, добавленного в базу данных. (Не забывайте, вложения должны быть связаны с сообщениями, с которыми они были приняты.) После того как идентификатор будет определен, для каждого из вложений созда¬ется SQL-запрос INSERT:
class AjaxMailbox {
// методы работы с базой данных
function checkMail() {
$рор = new Pop3(P0P3_SERVER, P0P3JJSER, P0P3_PASSW0RD);
if ($pop->login()) {
if ($pop->mailCount > 0) {
$conn = $this->connect(); $pop->getEraails();
foreach ($pop->messages as $message) { $query = "insert into AjaxMailMessages(To',CC,BCC, "Fr $query .=
"Subject,'Date',Message,HasAttachments,Folderld, $query .= " values('%s','%s','%s','%s','%s',%s,'%s'
.$message->hasAttachments.",1,1)"; $query = sprintf($query,
(addslashes($message->to)), (addslashes($message->cc)), (addslashes($message->bcc)), (addslashes($message->from)), (addslashes($message->subject)), $message->unixTimeStamp, (addslashes($message->getTextMess
);
$result = mysql_query($query, $conn);
if ($message->hasAttachments) {
$messageld = mysql_insert_id($conn);
foreach ($message->attachments as $attachment) f| r-, •■:■%<■■ $query = "insert into AjaxMailAttachments(Mes
Squery .= "Filename, ContentType, Size, Data)";
$query .= "values($messageld, '%s-,'%s.\'%s', 'lei
$query = sprintf($query,
addslashes($attachment->file $attachment->contentType, st rlen($attachment->data), addslashes($attachment->data)fcj
mysql query($query, $conn);
)

>
$this->disconnect($conn);
>
$pop->logoff();

}
// здесь находится остальной код
}
Для получения числового идентификатора последнего доба в таблицу сообщения предназначена функции mysql_insert_id(). J в цикле foreach производится обход всех вложений, пост сданным сообщением. Каждый элемент массива с вложениямиi ставляет собой ссылку на объект класса Pop3Attachment. Этот

держит информацию о конкретном вложении для данного сообщения ж обладает тремя свойствами: contentType, которое содержит тип MIME вложения, fileName, представляющего имя файла вложения, и data, которое может содержать либо текст, либо двоичные данные.
Для создания SQL-запроса, как и раньше, применяется функция sprintf (). Обратите внимание, что размер вложения определяется с по¬мощью функции strlen() - она получает размер вложения в байтах. После формирования текста запроса последний исполняется и добав¬ляет данные в таблицу AjaxMailAttachments. На этом работа метода checkMailO завершается.
Данный метод никогда не вызывается напрямую, только при выполне¬нии запроса к серверу. По сути метод checkMailO вызывается при вы¬полнении любого запроса, благодаря чему пользователь всегда будет иметь самую свежую информацию о состоянии своего почтового ящика.
Получение списка сообщений
Едва ли не самая обычная операция, выполняемая приложением, -это получение списка сообщении для отображения его перед пользова¬телем. Метод, отвечающий за выполнение этой операции, носит назва¬ние getFolderPage() и принимает два аргумента: числовой идентифика¬тор папки и номер страницы:
class AjaxMailbox {
// методы работы с базой данных
// метод проверки наличия новых сообщений
function getFolderPage($folder, $page) { $this->checkMail();
// здесь находится остальной код
>
В первую очередь метод getFolderPage() проверяет наличие новых сооб¬щений с помощью метода checkMailO. Если новые сообщения есть, то они будут добавлены в базу данных, благодаря чему любые запросы к базе данных, выполненные после этого, будут возвращать самую све¬жую информацию.
Следующий шаг заключается в том, чтобы сконструировать строку в формате JSON и отправить ее клиенту. Для этих целей определен универсальный класс JSONObject:
class JSONObject {
Экземпляр класса JSONOb j ect нужен для того, чтобы хранить данные, по¬ка не придет время преобразовать их в строку формата JSON. Этот объ¬ект хранит информацию о папке, необходимую методу getFolderPage().
Он содержит массу полезных сведений: общее число сообщений geCount), текущий номер страницы (page), общее число страниц Count), номер папки (folder), первое полученное сообщение (fi sage), общее число непрочитанных сообщений (unreadCount) и, массив с сообщениями на странице (messages). Структура д~ глядит так:
{
"messageCount":0,
"page":1,
"pageCount":1,
"folder":!,
"firstMessage":OV
"unreadCount": 0,
"messages":[]
}
Созданный объект класса JSONObject инициализируется инфо~ имеющей отношение к базе данных:
class AjaxMailbox {
// методы работы с базой данных
// метод проверки наличия новых сообщений
function getFolderPage($folder, $page) { $this->checkMail();
$conn = $this->connect();
Squery = "select count(Messageld) as count from AjaxMailMes? $query .= " where FolderId=$folder"; ;
$result = mysql_query($query, $conn); $row = mysql_fetch_assoc($result);
$info = new JSONObjectO;
$info->messageCount = (int) $row["count"]; . .
$info->page = $page;
$info->pageCount = (int) ceil($info"->messageCount/MESSAGES_ $info->folder = $folder;
$firstMessageNum = ($page-1) * MESSAGES_PER_PAGE; $info->firstMessage = $firstMessageNum+1; . $info->messages = arrayO;
$info->unreadCount = $this->getUnreadCount($conn);
// здесь находится остальной код
>
}
Общее количество сообщений в папке нетрудно получить с функции SQL count(). После создания объекта класса JSONObject
ва на него сохраняется в переменной $inf о, затем в свойство message-Gount записывается значение, полученное из базы данных. Далее но¬мер страницы записывается в свойство page (это то же самое значение, иоторое было передано методу в качестве входного аргумента). В свой¬ство pageCount записывается общее количество страниц для данной шапки. Оно определяется делением значения messageCount на константу *ESSAGES_PER_PAGE с последующим применением математической функ-иии округления вверх (до ближайшего большего целого числа). После «того в свойство folder заносится идентификационный номер папки.
Затем вычисляется индекс первого сообщения на странице и сохраня¬ется в переменной $firstMessageNum. Это число имеет очень большое аначение, поскольку помогает избежать извлечения из базы данных избыточного количества информации. После этого в свойство f irstMes-sage объекта $inf о записывается значение переменной $f irstMessageNum, увеличенное на единицу. Делается это потому, что данное число будет отображаться перед пользователем, который наверняка не захочет, чтобы нумерации сообщений начиналась с нуля. Первое сообщение всегда должно иметь порядковый номер 1. Потом создается и инициа¬лизируется пустым массивом свойство messages, позднее в этот массив будут записаны объекты с сообщениями.
На последнем шаге в этом фрагменте кода в свойство с именем unread-Count записывается количество непрочитанных сообщений. Это число извлекается с помощью метода getUn readCount (), который определен так:
class AjaxMailbox {
// прочие методы
с function getUn readCount ($conn) {
... Squery = "select count(Messageld) as UnreadCount from AjaxMailMessages";
$query .= " where FolderId=1 and Unread=1";
$result = mysql_query($query, $conn);
$row = mysql_fetch_assoc($resultj;
i' return intval($row["UnreadCount"]);

// прочие методы
}
Теперь пришло время получить конкретные почтовые сообщения. Для этого исполняется SQL-запрос, извлекающий все сообщения из задан¬ной папки, упорядочивая их по дате. Здесь в игру вступает номер пер¬вого сообщения - добавив в конец запроса оператор LIMIT, мы гаранти¬руем, что запрос извлечет только те сообщения, которые нам нужны:
class AjaxMailbox {
// методы работы с базой данных
// метод проверки наличия новых сообщений
function getFolderPage($folder, $page) { $this->checkMail();
$conn = $this->connect();
$query = "select count(Messageld) as count from AjaxMailMe $query .= " where FolderId=$folder";
Sresult = mysql_query($query, $conn); $row = mysql_fetch_assoc($result);
$info = new JSONObjectO; $info->messageCount = (int) $row["count"]; $info->page = $page;
$info->pageCount = (int) ceil($info->messageCount/MESSAGES_PBI $info->folder = $folder;
$firstMessageNum = ($page-1) « MESSAGES_PER_PAGE; $info->firstMessage = $firstMessageNum+1; $info->messages = arrayO;
$lnfo->unreadCount = $this->getUnreadCount($conn);
$query = "select * from AjaxMailMessages where Folderld=$fo' $query .= " order by date desc limit $firstMessageNum, ";
$result = mysql_query($query, $conn); // здесь находится остальной код
>
}
Данный SQL-запрос извлекает из таблицы все сообщения, в значение поля Folderld совпадает со значением переменной и возвращает их в порядке убывания по дате. Кроме того, пе влекается сообщение с номером $f irstMessageNum, причем общее чество извлекаемых сообщений ограничено числом MESSAGES.PER
Теперь у нас есть два возможных сценария развития событий: прос к базе выполнится успешно, либо он терпит неудачу. Для жения очень важно различать эти два исхода. К счастью, опр неудачное исполнение запроса к базе данных довольно просто, чае неудачи функция mysql_query() вернет значение false. Таких зом, убедиться в отсутствии ошибок можно простой проверкой ния переменной Sresult. Если в процессе исполнения запроса ла какая-либо ошибка, информация о ней может быть воз в свойстве error объекта $info. В противном случае необходимо все строки в полученном наборе данных, создать объект JSONObj каждой из них и добавить полученный объект в массив messages:
class AjaxMailbox {
// методы работы с базой данных
// метод проверки наличия новых сообщений
function getFolderPage($folder, $page) { $this->checkMail();
$conn = $this->connect();
$query = "select count(Messageld) as count from AjaxMailMessages"; Squery .= " where FolderId=$folder";
$result = mysql_query($query, $conn); $row = mysql_fetch_assoc($result);
Sinfo = new JSONObject(); $info->messageCount = (int) $row["count"]; $info->page = $page;
$info->pageCount = (int) ceil($info->messageCount/MESSAGES_PER_PAGE); $info->folder = $folder;
SfirstMessageNum = ($page-1) * MESSAGES_PER_PAGE; $info->firstMessage = $firstMessageNum+1; $info->messages = array();
$info->unreadCount = $this->getUnreadCount($conn);
Squery = "select * from AjaxMailMessages where FolderId=$folder"; Squery .= " order by date desc limit SfirstMessageNum, "; Squery .= MESSAGES_PER_PAGE;
Sresult = mysql_query($query, Sconn);
if (!Sresult) <
$info->error = mysql_error($conn); } else {
while ($row = mysql_fetch_assoc(Sresult)) { Smessage = new JS0N0bject(); $message->id = $row["Messageld']; $message->from = $row['From']; $message->subject = $row['Subject']; $message->date = dateC'M j Y", intval($ row["Date"])); ;. $message->hasAttachments = ($row['HasAttachments'] == 1); $message->unread =($row[ Unread']==1); $info->messages[] = Smessage;
В данном фрагменте кода сначала проверяется переменная Sresult. Ес¬ли запрос потерпел неудачу, в свойство error объекта $info записывает¬ся сообщение об ошибке, полученное с помощью функции mysql_er ror(). Клиентская часть приложения сможет проверить это свойство и опре¬делить наличие ошибки. Если запрос был выполнен благополучно, то создается новый экземпляр класса JSONObject, который будет сохранен в массиве messages. Этот объект заполняется информацией, полученной из объекта $row, при этом особое внимание обращается на< представления даты сообщения, чтобы отображались только день и год. (Благодаря этому отпадает необходимость формат! даты в JavaScript на стороне клиента.) Кроме того, поскольку по Attachments и Unread битовые, они сравниваются со значением 1,1 зультаты сравнения (логические значения) записываются в сс вующие свойства объекта Smesasge. В последней строке в цикле* объект $message вставляется в конец массива $messages.
После выполнения всех действий можно закрыть соединение с t данных (с помощью функции disconnect)) и вернуть объект $infoJ программа, вызвавшая метод getFolderPage(), должна преобр полученный объект в строку формата JSON и отправить ее клие