Вдохновившись темой получения статусов мессенджеров на PHP, я решил структурировать код получения статусов, так и родился мой небольшой проект.
Основная концепция моего проекта такова:
1. ООП
2. Использование универсальных и удобных велосипедов классов для основных и вспомогательных функций
3. Получение статуса как описанного в enum кода, но не текстовым или иным сообщением, отделение вида от контроллера.
Механизм получения того или иного статуса честно украден из исследований автора первоначальной статьи и, в целом, не отличаются. В качестве механизма получения используется готовый класс загрузки, основанный как на cUrl, так и родном для PHP file_get_contents, скачивать содержание страницы можно с HTTP заголовками или без, проставляя соответствующий параметр.
Как было описано выше, коды статусов содержатся в особом enum, коды ошибок располагаются рядом. Не каждый из получателей статусов может использовать все типы статусов, но все возможные перечислены тут:
class enmIMStatus
{
const imsOffline = 0x00;
const imsOnline = 0x01;
const imsAway = 0x02;
const imsDoNotDisturb = 0x03;
const imsNotAvailable = 0x04;
const imsFreeForChat = 0x05;
}
class enmImError
{
const imeNoError = 0x00;
const imeBadIdentity = 0x01;
const imeUnknownStatus = 0x02;
const imeConnectionErr = 0x03;
}
Основной класс получения статуса tBasicIMGetter абстрактен, содержит общий функционал для каждого из получателей статусов — конструктор, создающий копию базового скачивателя страниц и создающий массив предкешированных статусов. Такой массив будет необходим для грязного кода, где функция получения класса может быть вызвана несколько раз.
Статусы можно предварительно подгрузить (например, из БД) функцией preloadStatuses($aStatuses), массив $aStatuses должен быть представлен в формате id_месседжера => код_статуса.
Получение статуса происходит функцией getImStatus($aIdentity), параметром которой является ID месседжера, для ICQ — это номер, для Mail.ru Agent — адрес почтового ящика…
Базовый класс имеет две абстрактных функции — непосредственное получение статуса и проверка ID на соответствие типу месседжера. Эти функции составляют основу каждого из специализированных получателей статусов.
abstract protected function doUpdateImStatus($aIdentity);
abstract protected function checkImIdentity($aIdentity);
На текущее время, в проекте поддерживаются следующие типы месседжеров: ICQ, Skype, Jabber, VK, Mail.Ru Agent. Каждый из получателей статусов реализован как класс, наследованный от базового tBasicIMGetter.
На примере ICQ такой класс будет выглядить так:
class tICQStatusGetter extends tBasicIMGetter
{
protected function checkImIdentity($aIdentity)
{
return !empty($aIdentity) && is_numeric($aIdentity) && (intval($aIdentity) > 10000) ? intval($aIdentity) : false;
}
protected function doUpdateImStatus($aIdentity)
{
$lContents = $this->fCDownloader->getURLContents('http://status.icq.com/online.gif?icq=' . $aIdentity . '&img=27', true);
if(!empty($lContents))
{
$lGotStatus = false;
if(strstr($lContents, 'online1'))
$lGotStatus = enmIMStatus::imsOnline;
elseif(strstr($lContents, 'online0'))
$lGotStatus = enmIMStatus::imsOffline;
elseif(strstr($lContents, 'online2'))
$lGotStatus = enmIMStatus::imsAway;
if($lGotStatus !== false)
{
$this->fLastError = enmImError::imeNoError;
$this->doUpdateCachedStatus($aIdentity, $lGotStatus);
}
else
$this->fLastError = enmImError::imeUnknownStatus;
}
else
$this->fLastError = enmImError::imeConnectionErr;
}
}
После получения содержания загружаемого документа, происходит его разбор и соответствующее проставление статуса относительно заданного IM id.
Немного кода быстрые функции и проверка ошибок. Если что-то не сработает, на выходе будет значится, что пользователь с заданным ID не в сети.
В качестве примера получения статусов я набросал следующий код, демонстрирующий функционал каждого из получателей статусов:
$lIMStatusesInText = array(
enmIMStatus::imsOffline => 'Offline',
enmIMStatus::imsOnline => 'Online',
enmIMStatus::imsAway => 'Away',
enmIMStatus::imsDoNotDisturb => 'Do not disturb',
enmIMStatus::imsNotAvailable => 'Available',
enmIMStatus::imsFreeForChat => 'Free for chat'
);
$lImStatusGetters = array();
$lImStatusGetters['icq'] = new tICQStatusGetter();
$lImStatusGetters['jabber'] = new tJabberStatusGetter();
$lImStatusGetters['mail.ru agent'] = new tMRAStatusGetter();
$lImStatusGetters['skype'] = new tSkypeStatusGetter();
$lImStatusGetters['vkontakte'] = new tVKStatusGetter();
$lImIdentificators = array(
'icq' => 'номер_icq',
'jabber' => 'хеш_от_jid',
'mail.ru agent' => 'адрес_на_mail.ru',
'skype' => 'логин_skype',
'vkontakte' => 'id_или_имя_вконтакте',
);
foreach($lImStatusGetters as $lKey => &$lGetter)
echo $lKey, ': ', $lIMStatusesInText[$lGetter->getImStatus($lImIdentificators[$lKey])], '<br>', PHP_EOL;
В соответствии с правилами хорошего тона, код проекта доступен на github: github.com/Urvin/IM-Statuses-for-PHP
Надеюсь, кому-нибудь да будет полезно.
Автор: Urvin