Удобные классы для получения статусов IM на PHP

в 8:11, , рубрики: ICQ, jabber, mra, php, skype, Песочница, метки: , , , , ,

Вдохновившись темой получения статусов мессенджеров на 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

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js