Current Path : /var/www/html/clients/e-nkama.ru/e-nkama_bitrix/bitrix/modules/pull/classes/general/ |
Current File : /var/www/html/clients/e-nkama.ru/e-nkama_bitrix/bitrix/modules/pull/classes/general/pull_push.php |
<? IncludeModuleLangFile(__FILE__); require_once('pushservices/services_descriptions.php'); class CPullPush { protected static function PrepareSql(&$arFields, $arOrder, &$arFilter, $arSelectFields) { global $DB; $strSqlSelect = ""; $strSqlFrom = ""; $strSqlWhere = ""; $strSqlGroupBy = ""; $strSqlOrderBy = ""; $strSqlLimit = ""; $arGroupByFunct = Array(); // SELECT --> $arFieldsKeys = array_keys($arFields); $arAlreadyJoined = Array(); if (isset($arSelectFields) && !is_array($arSelectFields) && is_string($arSelectFields) && strlen($arSelectFields)>0 && array_key_exists($arSelectFields, $arFields)) $arSelectFields = array($arSelectFields); if (!isset($arSelectFields) || !is_array($arSelectFields) || count($arSelectFields)<=0 || in_array("*", $arSelectFields)) { $countFieldsKeys = count($arFieldsKeys); for ($i = 0; $i < $countFieldsKeys; $i++) { if (isset($arFields[$arFieldsKeys[$i]]["WHERE_ONLY"]) && $arFields[$arFieldsKeys[$i]]["WHERE_ONLY"] == "Y") { continue; } if (strlen($strSqlSelect) > 0) $strSqlSelect .= ", "; if ($arFields[$arFieldsKeys[$i]]["FIELD_TYPE"] == "datetime") { if ((strtoupper($DB->type)=="ORACLE" || strtoupper($DB->type)=="MSSQL") && (array_key_exists($arFieldsKeys[$i], $arOrder))) $strSqlSelect .= $arFields[$arFieldsKeys[$i]]["FIELD_NAME"]." as ".$arFieldsKeys[$i]."_X1, "; $strSqlSelect .= $DB->DateToCharFunction($arFields[$arFieldsKeys[$i]]["FIELD_NAME"], "FULL")." as ".$arFieldsKeys[$i]; } elseif ($arFields[$arFieldsKeys[$i]]["FIELD_TYPE"] == "date") { if ((strtoupper($DB->type)=="ORACLE" || strtoupper($DB->type)=="MSSQL") && (array_key_exists($arFieldsKeys[$i], $arOrder))) $strSqlSelect .= $arFields[$arFieldsKeys[$i]]["FIELD_NAME"]." as ".$arFieldsKeys[$i]."_X1, "; $strSqlSelect .= $DB->DateToCharFunction($arFields[$arFieldsKeys[$i]]["FIELD_NAME"], "SHORT")." as ".$arFieldsKeys[$i]; } else $strSqlSelect .= $arFields[$arFieldsKeys[$i]]["FIELD_NAME"]." as ".$arFieldsKeys[$i]; if (isset($arFields[$arFieldsKeys[$i]]["FROM"]) && strlen($arFields[$arFieldsKeys[$i]]["FROM"]) > 0 && !in_array($arFields[$arFieldsKeys[$i]]["FROM"], $arAlreadyJoined)) { if (strlen($strSqlFrom) > 0) $strSqlFrom .= " "; $strSqlFrom .= $arFields[$arFieldsKeys[$i]]["FROM"]; $arAlreadyJoined[] = $arFields[$arFieldsKeys[$i]]["FROM"]; } } } else { foreach ($arSelectFields as $key => $val) { $val = strtoupper($val); $key = strtoupper($key); if (array_key_exists($val, $arFields)) { if (strlen($strSqlSelect) > 0) $strSqlSelect .= ", "; if (in_array($key, $arGroupByFunct)) { $strSqlSelect .= $key."(".$arFields[$val]["FIELD_NAME"].") as ".$val; } else { if ($arFields[$val]["FIELD_TYPE"] == "datetime") { if ((strtoupper($DB->type)=="ORACLE" || strtoupper($DB->type)=="MSSQL") && (array_key_exists($val, $arOrder))) $strSqlSelect .= $arFields[$val]["FIELD_NAME"]." as ".$val."_X1, "; $strSqlSelect .= $DB->DateToCharFunction($arFields[$val]["FIELD"], "FULL")." as ".$val; } else $strSqlSelect .= $arFields[$val]["FIELD_NAME"]." as ".$val; } if (isset($arFields[$val]["FROM"]) && strlen($arFields[$val]["FROM"]) > 0 && !in_array($arFields[$val]["FROM"], $arAlreadyJoined)) { if (strlen($strSqlFrom) > 0) $strSqlFrom .= " "; $strSqlFrom .= $arFields[$val]["FROM"]; $arAlreadyJoined[] = $arFields[$val]["FROM"]; } } } } // <-- SELECT // WHERE --> $obWhere = new CSQLWhere; $obWhere->SetFields($arFields); $strSqlWhere = $obWhere->GetQuery($arFilter); // ORDER BY --> $arSqlOrder = Array(); foreach ($arOrder as $by => $order) { $by = strtoupper($by); $order = strtoupper($order); if ($order != "ASC") $order = "DESC"; else $order = "ASC"; if (array_key_exists($by, $arFields)) { $arSqlOrder[] = " ".$arFields[$by]["FIELD_NAME"]." ".$order." "; if (isset($arFields[$by]["FROM"]) && strlen($arFields[$by]["FROM"]) > 0 && !in_array($arFields[$by]["FROM"], $arAlreadyJoined)) { if (strlen($strSqlFrom) > 0) $strSqlFrom .= " "; $strSqlFrom .= $arFields[$by]["FROM"]; $arAlreadyJoined[] = $arFields[$by]["FROM"]; } } } $strSqlOrderBy = ""; DelDuplicateSort($arSqlOrder); $countSqlOrder = count($arSqlOrder); for ($i=0; $i<$countSqlOrder; $i++) { if (strlen($strSqlOrderBy) > 0) $strSqlOrderBy .= ", "; if(strtoupper($DB->type)=="ORACLE") { if(substr($arSqlOrder[$i], -3)=="ASC") $strSqlOrderBy .= $arSqlOrder[$i]." NULLS FIRST"; else $strSqlOrderBy .= $arSqlOrder[$i]." NULLS LAST"; } else $strSqlOrderBy .= $arSqlOrder[$i]; } // <-- ORDER BY return array( "SELECT" => $strSqlSelect, "FROM" => $strSqlFrom, "WHERE" => $strSqlWhere, "GROUPBY" => $strSqlGroupBy, "ORDERBY" => $strSqlOrderBy, ); } public static function GetList($arOrder = array(), $arFilter = array(),$arSelect = array(), $arNavStartParams = Array()) { global $DB; $arFields = array( "ID" => array("FIELD_NAME" => "R.ID", "FIELD_TYPE" => "int"), "USER_ID" => array("FIELD_NAME" => "R.USER_ID", "FIELD_TYPE" => "int"), "APP_ID" => array("FIELD_NAME" => "R.APP_ID", "FIELD_TYPE" => "string"), "UNIQUE_HASH" => array("FIELD_NAME" => "R.UNIQUE_HASH", "FIELD_TYPE" => "string"), "DEVICE_TYPE" => array("FIELD_NAME" => "R.DEVICE_TYPE", "FIELD_TYPE" => "string"), "DEVICE_ID" => array("FIELD_NAME" => "R.DEVICE_ID", "FIELD_TYPE" => "string"), "DEVICE_NAME" => array("FIELD_NAME" => "R.DEVICE_NAME", "FIELD_TYPE" => "string"), "DEVICE_TOKEN" => array("FIELD_NAME" => "R.DEVICE_TOKEN", "FIELD_TYPE" => "string"), "DATE_CREATE" => array("FIELD_NAME" => "R.DATE_CREATE", "TYPE" => "datetime"), "DATE_AUTH" => array("FIELD_NAME" => "R.DATE_AUTH", "TYPE" => "datetime"), ); $arSqls = self::PrepareSql($arFields, $arOrder, $arFilter,$arSelect); $strSql = "SELECT ".$arSqls["SELECT"]." FROM b_pull_push R ". (strlen($arSqls["WHERE"])<=0 ? "" : "WHERE ".$arSqls["WHERE"]). (strlen($arSqls["ORDERBY"])<=0 ? "" : " ORDER BY ".$arSqls["ORDERBY"]); if(is_array($arNavStartParams) && intval($arNavStartParams["nTopCount"])>0) $strSql = $DB->TopSql($strSql, $arNavStartParams["nTopCount"]); // echo "<pre>".$strSql."</pre>"; $res = $DB->Query($strSql, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__); return $res; } public static function Add($arFields = Array()) { global $DB; if (!self::CheckFields("ADD", $arFields)) return false; $arInsert = $DB->PrepareInsert("b_pull_push", $arFields); $strSql ="INSERT INTO b_pull_push(".$arInsert[0].", DATE_CREATE, DATE_AUTH) ". "VALUES(".$arInsert[1].", ".$DB->CurrentTimeFunction().", ".$DB->CurrentTimeFunction().")"; // echo $strSql ; $ID = $DB->Query($strSql, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__); CAgent::AddAgent("CPullPush::cleanTokens();", "pull", "N", 43200, "", "Y", ConvertTimeStamp(time() + CTimeZone::GetOffset() + 30, "FULL")); return $ID; } public static function Update($ID, $arFields = Array()) { global $DB; $ID = intval($ID); if (!self::CheckFields("UPDATE", $arFields) || $ID<=0) return false; $arFields["DATE_AUTH"] = ConvertTimeStamp(getmicrotime(), "FULL"); $strUpdate = $DB->PrepareUpdate("b_pull_push", $arFields); $strSql = "UPDATE b_pull_push SET ".$strUpdate." WHERE ID=".$ID; $ID = $DB->Query($strSql, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__); return $ID; } public static function CheckFields($type = "ADD", &$arFields = Array()) { $pm = new CPushManager(); $arDeviceTypes = array_keys($pm->getServices()); $arFields["USER_ID"] = intval($arFields["USER_ID"]); if (!is_array($arFields) || empty($arFields)) return false; if (!$arFields["DEVICE_TOKEN"]||!$arFields["DEVICE_ID"]||intval($arFields["USER_ID"])<=0) return false; if (!$arFields["DEVICE_TYPE"] || !in_array($arFields["DEVICE_TYPE"],$arDeviceTypes)) return false; if(!preg_match('~^[a-f0-9]{64}$~i', $arFields["DEVICE_TOKEN"]) && $arFields["DEVICE_TYPE"] == "APPLE") return false; if($type == "ADD") { if(!$arFields["DEVICE_NAME"] ) $arFields["DEVICE_NAME"] = $arFields["DEVICE_ID"]; } if ($arFields["DATE_AUTH"]) { unset($arFields["DATE_AUTH"]); } if(!$arFields["APP_ID"]) $arFields["APP_ID"] = "Bitrix24"; $arFields["UNIQUE_HASH"] = self::getUniqueHash($arFields["USER_ID"], $arFields["APP_ID"]); return true; } public static function Delete($ID = false) { global $DB; $ID = intval($ID); if ($ID<=0) return false; $strSql = "DELETE from b_pull_push WHERE ID=".$ID; $DB->Query($strSql, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__); return true; } public static function getUniqueHash($user_id, $app_id) { return md5($user_id.$app_id); } public static function cleanTokens() { global $DB; /** * @var $DB CAllDatabase */ $killTime = ConvertTimeStamp(getmicrotime() - 24 * 3600 * 14, "FULL"); $sqlString = "DELETE FROM b_pull_push WHERE DATE_AUTH < ". $DB->CharToDateFunction($killTime); $DB->Query($sqlString, false, "FILE: " . __FILE__ . "<br> LINE: " . __LINE__); return "CPullPush::cleanTokens();"; } } class CPushManager { const SEND_IMMEDIATELY = 0; const SEND_DEFERRED = 1; const SEND_SKIP = 2; const RECORD_NOT_FOUND = 3; public static $pushServices = false; private static $remoteProviderUrl = "https://cloud-messaging.bitrix24.com/send/"; public function __construct() { if(!is_array(self::$pushServices)) { self::$pushServices = array(); foreach(GetModuleEvents("pull", "OnPushServicesBuildList", true) as $arEvent) { $res = ExecuteModuleEventEx($arEvent); if(is_array($res)) { if(!is_array($res[0])) $res = array($res); foreach($res as $serv) self::$pushServices[$serv["ID"]] = $serv; } } } } public function AddQueue($arParams) { if (!CPullOptions::GetPushStatus()) return false; global $DB; if (is_array($arParams['USER_ID'])) { foreach ($arParams['USER_ID'] as $key => $userId) { $userId = intval($userId); if ($userId > 0) { $arFields['USER_ID'][$userId] = $userId; } } if (empty($arFields['USER_ID'])) { return false; } } else if (isset($arParams['USER_ID']) && intval($arParams['USER_ID']) > 0) { $userId = intval($arParams['USER_ID']); $arFields['USER_ID'][$userId] = $userId; } else { return false; } if (isset($arParams['MESSAGE']) && strlen(trim($arParams['MESSAGE'])) > 0) { $arFields['MESSAGE'] = str_replace(Array("\r\n", "\n\r", "\n", "\r"), " ", trim($arParams['MESSAGE'])); } $arFields['TAG'] = ''; if (isset($arParams['TAG']) && strlen(trim($arParams['TAG'])) > 0 && strlen(trim($arParams['TAG'])) <= 255) $arFields['TAG'] = trim($arParams['TAG']); $arFields['SUB_TAG'] = ''; if (isset($arParams['SUB_TAG']) && strlen(trim($arParams['SUB_TAG'])) > 0 && strlen(trim($arParams['SUB_TAG'])) <= 255) $arFields['SUB_TAG'] = trim($arParams['SUB_TAG']); $arFields['BADGE'] = -1; if (isset($arParams['BADGE']) && $arParams['BADGE'] != '' && intval($arParams['BADGE']) >= 0) $arFields['BADGE'] = intval($arParams['BADGE']); $arFields['PARAMS'] = ''; if (isset($arParams['PARAMS'])) { if (is_array($arParams['PARAMS']) || strlen(trim($arParams['PARAMS'])) > 0) { $arFields['PARAMS'] = $arParams['PARAMS']; } } $arFields['ADVANCED_PARAMS'] = Array(); if (isset($arParams['ADVANCED_PARAMS']) && is_array($arParams['ADVANCED_PARAMS'])) { $arFields['ADVANCED_PARAMS'] = $arParams['ADVANCED_PARAMS']; } if (!isset($arParams['ADVANCED_PARAMS']['id']) && strlen($arFields['SUB_TAG']) > 0) { $arParams['ADVANCED_PARAMS']['id'] = $arFields['SUB_TAG']; } if (strlen($arParams['SOUND']) > 0) $arFields['SOUND'] = $arParams['SOUND']; $arFields['APP_ID'] = (strlen($arParams['APP_ID']) > 0)? $arParams['APP_ID']: "Bitrix24"; $groupMode = Array( self::SEND_IMMEDIATELY => Array(), self::SEND_DEFERRED => Array(), ); $devices = Array(); $info = self::GetDeviceInfo($arFields['USER_ID'], $arFields['APP_ID']); foreach ($info as $userId => $params) { if ($params['mode'] != self::RECORD_NOT_FOUND && isset($arParams['SEND_IMMEDIATELY']) && $arParams['SEND_IMMEDIATELY'] == 'Y') { $params['mode'] = self::SEND_IMMEDIATELY; } $groupMode[$params['mode']][$userId] = $userId; if ($params['mode'] == self::SEND_IMMEDIATELY && !empty($params['device'])) { $devices = array_merge($devices, $params['device']); } } $pushImmediately = Array(); foreach ($groupMode[self::SEND_IMMEDIATELY] as $userId) { $arAdd = Array( 'USER_ID' => $userId, ); if (is_array($arFields['PARAMS'])) { if (isset($arFields['PARAMS']['CATEGORY'])) { $arAdd['CATEGORY'] = $arFields['PARAMS']['CATEGORY']; unset($arFields['PARAMS']['CATEGORY']); } $arAdd['PARAMS'] = Bitrix\Main\Web\Json::encode($arFields['PARAMS']); } elseif (strlen($arFields['PARAMS']) > 0) { $arAdd['PARAMS'] = $arFields['PARAMS']; } if (strlen($arFields['MESSAGE']) > 0) $arAdd['MESSAGE'] = $arFields['MESSAGE']; if (intval($arFields['BADGE']) >= 0) $arAdd['BADGE'] = $arFields['BADGE']; if (strlen($arFields['SOUND']) > 0) $arAdd['SOUND'] = $arFields['SOUND']; if(strlen($arParams['EXPIRY']) > 0) $arAdd['EXPIRY'] = $arParams['EXPIRY']; if(count($arParams['ADVANCED_PARAMS']) > 0) $arAdd['ADVANCED_PARAMS'] = $arParams['ADVANCED_PARAMS']; $arAdd['APP_ID'] = $arFields['APP_ID']; $pushImmediately[] = $arAdd; } if (!empty($pushImmediately)) { $CPushManager = new CPushManager(); $CPushManager->SendMessage($pushImmediately, $devices); } foreach ($groupMode[self::SEND_DEFERRED] as $userId) { $arAdd = Array( 'USER_ID' => $userId, 'TAG' => $arFields['TAG'], 'SUB_TAG' => $arFields['SUB_TAG'], '~DATE_CREATE' => $DB->CurrentTimeFunction() ); if (strlen($arFields['MESSAGE']) > 0) $arAdd['MESSAGE'] = $arFields['MESSAGE']; if (is_array($arFields['ADVANCED_PARAMS'])) $arAdd['ADVANCED_PARAMS'] = Bitrix\Main\Web\Json::encode($arFields['ADVANCED_PARAMS']); if (is_array($arFields['PARAMS'])) $arAdd['PARAMS'] = Bitrix\Main\Web\Json::encode($arFields['PARAMS']); else if (strlen($arFields['PARAMS']) > 0) $arAdd['PARAMS'] = $arFields['PARAMS']; if (intval($arFields['BADGE']) >= 0) $arAdd['BADGE'] = $arFields['BADGE']; $arAdd['APP_ID'] = $arFields['APP_ID']; $DB->Add("b_pull_push_queue", $arAdd, Array("MESSAGE", "PARAMS")); CAgent::AddAgent("CPushManager::SendAgent();", "pull", "N", 30, "", "Y", ConvertTimeStamp(time()+CTimeZone::GetOffset()+30, "FULL"), 100, false, false); } return true; } public static function DeleteFromQueueByTag($userId, $tag, $appId = 'Bitrix24') { global $DB; if (strlen($tag) <= 0 || intval($userId) == 0) return false; $strSql = "DELETE FROM b_pull_push_queue WHERE USER_ID = ".intval($userId)." AND TAG = '".$DB->ForSQL($tag)."'"; $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); $CPushManager = new CPushManager(); $CPushManager->AddQueue(Array( 'USER_ID' => intval($userId), 'ADVANCED_PARAMS' => Array( "notificationsToCancel" => array($tag), ), 'SEND_IMMEDIATELY' => 'Y', 'APP_ID' => $appId )); return true; } public static function DeleteFromQueueBySubTag($userId, $tag, $appId = 'Bitrix24') { global $DB; if (strlen($tag) <= 0 || intval($userId) == 0) return false; $strSql = "DELETE FROM b_pull_push_queue WHERE USER_ID = ".intval($userId)." AND SUB_TAG = '".$DB->ForSQL($tag)."'"; $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); $CPushManager = new CPushManager(); $CPushManager->AddQueue(Array( 'USER_ID' => intval($userId), 'ADVANCED_PARAMS' => Array( "notificationsToCancel" => array($tag), ), 'SEND_IMMEDIATELY' => 'Y', 'APP_ID' => $appId )); return true; } public static function GetDeviceInfo($userId, $appId = 'Bitrix24') { $result = Array(); if (is_array($userId)) { foreach ($userId as $key => $id) { $id = intval($id); if ($id > 0) { $result[$id] = Array( 'mode' => self::RECORD_NOT_FOUND, 'device' => Array(), ); } } } else if (intval($userId) > 0) { $result[intval($userId)] = Array( 'mode' => self::RECORD_NOT_FOUND, 'device' => Array(), ); } if (empty($result)) { return false; } $imInclude = false; if (CModule::IncludeModule('im')) $imInclude = true; $query = new \Bitrix\Main\Entity\Query(\Bitrix\Main\UserTable::getEntity()); $sago = Bitrix\Main\Application::getConnection()->getSqlHelper()->addSecondsToDateTime('-180'); $query->registerRuntimeField('', new \Bitrix\Main\Entity\ExpressionField('IS_ONLINE_CUSTOM', 'CASE WHEN LAST_ACTIVITY_DATE > '.$sago.' THEN \'Y\' ELSE \'N\' END')); $query->addSelect('ID')->addSelect('EMAIL')->addSelect('IS_ONLINE_CUSTOM'); if ($imInclude) { $query->registerRuntimeField('', new \Bitrix\Main\Entity\ReferenceField('im', 'Bitrix\Im\StatusTable', array('=this.ID' => 'ref.USER_ID'))); $query->addSelect('im.IDLE', 'IDLE')->addSelect('im.MOBILE_LAST_DATE', 'MOBILE_LAST_DATE'); } $query->registerRuntimeField('', new \Bitrix\Main\Entity\ReferenceField('push', 'Bitrix\Pull\PushTable', array('=this.ID' => 'ref.USER_ID'))); $query->registerRuntimeField('', new \Bitrix\Main\Entity\ExpressionField('HAS_MOBILE', 'CASE WHEN main_user_push.USER_ID > 0 THEN \'Y\' ELSE \'N\' END')); $query->addSelect('HAS_MOBILE') ->addSelect('push.APP_ID', 'APP_ID') ->addSelect('push.UNIQUE_HASH', 'UNIQUE_HASH') ->addSelect('push.DEVICE_TYPE', 'DEVICE_TYPE') ->addSelect('push.DEVICE_TOKEN', 'DEVICE_TOKEN'); $query->addFilter('=ID', array_keys($result)); $queryResult = $query->exec(); while ($user = $queryResult->fetch()) { $uniqueHashes[] = CPullPush::getUniqueHash($user["ID"], $appId); $uniqueHashes[] = CPullPush::getUniqueHash($user["ID"], $appId."_bxdev"); if (in_array($user['UNIQUE_HASH'], $uniqueHashes)) { $result[$user['ID']]['device'][] = Array( 'APP_ID' => $user['APP_ID'], 'USER_ID' => $user['ID'], 'DEVICE_TYPE' => $user['DEVICE_TYPE'], 'DEVICE_TOKEN' => $user['DEVICE_TOKEN'], ); //$result[$user['ID']]['email'] = $user['EMAIL']; } else { continue; } if ($result[$user['ID']]['mode'] != self::RECORD_NOT_FOUND) { continue; } $isMobile = false; $isOnline = false; $isDesktop = false; $isDesktopIdle = false; if ($user['HAS_MOBILE'] == 'N') { $result[$user['ID']]['mode'] = self::RECORD_NOT_FOUND; $result[$user['ID']]['device'] = Array(); continue; } if ($user['IS_ONLINE_CUSTOM'] == 'Y') { $isOnline = true; } if ($imInclude) { $mobileLastDate = 0; if (is_object($user['MOBILE_LAST_DATE'])) { $mobileLastDate = $user['MOBILE_LAST_DATE']->getTimestamp(); } if ($mobileLastDate > 0 && $mobileLastDate + 180 > time()) { $isMobile = true; } $isDesktop = CIMMessenger::CheckDesktopStatusOnline($user['ID']); if ($isDesktop && $isOnline && is_object($user['IDLE'])) { if ($user['IDLE']->getTimestamp() > 0) { $isDesktopIdle = true; } } } $status = self::SEND_IMMEDIATELY; if ($isMobile) { $status = self::SEND_IMMEDIATELY; } else if ($isOnline) { $status = self::SEND_DEFERRED; if ($isDesktop) { $status = self::SEND_SKIP; if ($isDesktopIdle) { $status = self::SEND_IMMEDIATELY; } else { $result[$user['ID']]['device'] = Array(); } } else { $result[$user['ID']]['device'] = Array(); } } $result[$user['ID']]['mode'] = $status; } return $result; } public static function SendAgent() { global $DB; if (!CPullOptions::GetPushStatus()) return false; $count = 0; $maxId = 0; $pushLimit = 70; $arPush = Array(); $sqlDate = ""; $dbType = strtolower($DB->type); if ($dbType== "mysql") $sqlDate = " WHERE DATE_CREATE < DATE_SUB(NOW(), INTERVAL 15 SECOND) "; else if ($dbType == "mssql") $sqlDate = " WHERE DATE_CREATE < dateadd(SECOND, -15, getdate()) "; else if ($dbType == "oracle") $sqlDate = " WHERE DATE_CREATE < SYSDATE-(1/24/60/60*15) "; $strSql = $DB->TopSql("SELECT ID, USER_ID, MESSAGE, PARAMS, ADVANCED_PARAMS, BADGE, APP_ID FROM b_pull_push_queue".$sqlDate, 280); $dbRes = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); while ($arRes = $dbRes->Fetch()) { if ($arRes['BADGE'] == '') unset($arRes['BADGE']); $arRes['PARAMS'] = $arRes['PARAMS']? Bitrix\Main\Web\Json::decode($arRes['PARAMS']): ""; if (is_array($arRes['PARAMS'])) { if (isset($arRes['PARAMS']['CATEGORY'])) { $arRes['CATEGORY'] = $arRes['PARAMS']['CATEGORY']; unset($arRes['PARAMS']['CATEGORY']); } $arRes['PARAMS'] = Bitrix\Main\Web\Json::encode($arRes['PARAMS']); } $arRes['ADVANCED_PARAMS'] = strlen($arRes['ADVANCED_PARAMS']) > 0? Bitrix\Main\Web\Json::decode($arRes['ADVANCED_PARAMS']): Array(); $arPush[$count][] = $arRes; if ($pushLimit <= count($arPush[$count])) $count++; $maxId = $maxId < $arRes['ID']? $arRes['ID']: $maxId; } if ($maxId > 0) { $strSql = "DELETE FROM b_pull_push_queue WHERE ID <= ".$maxId; $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); } $CPushManager = new CPushManager(); foreach ($arPush as $arStack) { $CPushManager->SendMessage($arStack); } $strSql = "SELECT COUNT(ID) CNT FROM b_pull_push_queue"; $dbRes = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); if ($arRes = $dbRes->Fetch()) { global $pPERIOD; if ($arRes['CNT'] > 280) { $pPERIOD = 10; return "CPushManager::SendAgent();"; } else if ($arRes['CNT'] > 0) { $pPERIOD = 30; return "CPushManager::SendAgent();"; } } return false; } public function SendMessage($arMessages = Array(), $arDevices = Array()) { if(empty($arMessages)) return false; $uniqueHashes = Array(); $arTmpMessages = Array(); foreach ($arMessages as $message) { if(!$message["USER_ID"]) continue; $uniqueHashes[] = CPullPush::getUniqueHash($message["USER_ID"], $message["APP_ID"]); $uniqueHashes[] = CPullPush::getUniqueHash($message["USER_ID"], $message["APP_ID"]."_bxdev"); if(!array_key_exists("USER_".$message["USER_ID"], $arTmpMessages)) $arTmpMessages["USER_".$message["USER_ID"]] = Array(); $arTmpMessages["USER_".$message["USER_ID"]][] = htmlspecialcharsback($message); } $filter = array( "UNIQUE_HASH" => array_unique($uniqueHashes) ); if (empty($arDevices)) { $dbDevices = CPullPush::GetList(Array("DEVICE_TYPE" => "ASC"), $filter); while($row = $dbDevices->Fetch()) { $arDevices[] = $row; } } $arServicesIDs = array_keys(self::$pushServices); $arPushMessages = Array(); foreach ($arDevices as $arDevice) { if(in_array($arDevice["DEVICE_TYPE"], $arServicesIDs)) { $tmpMessage = $arTmpMessages["USER_" . $arDevice["USER_ID"]]; $mode = "PRODUCTION"; if(strpos($arDevice["APP_ID"], "_bxdev")>0) $mode = "SANDBOX"; $arPushMessages[$arDevice["DEVICE_TYPE"]][$arDevice["DEVICE_TOKEN"]] = Array( "messages"=>$tmpMessage, "mode"=>$mode ); } } if(empty($arPushMessages)) return false; $batch = ""; /** * @var CPushService $obPush */ foreach($arServicesIDs as $serviceID) { if($arPushMessages[$serviceID]) { if (class_exists(self::$pushServices[$serviceID]["CLASS"])) { $obPush = new self::$pushServices[$serviceID]["CLASS"]; if (method_exists($obPush, "getBatch")) { $batch .= $obPush->getBatch($arPushMessages[$serviceID]); } } } } $this->sendBatch($batch); return true; } public function sendBatch($batch) { require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/classes/general/update_client.php"); $key = CUpdateClient::GetLicenseKey(); if(strlen($key)>0 && strlen($batch)>0) { $request = new CHTTP(); $arPostData = Array( "Action"=>"SendMessage", "MessageBody" =>$batch ); $postdata = CHTTP::PrepareData($arPostData); $arUrl = $request->ParseURL(self::$remoteProviderUrl."?key=".md5($key), false); $request->Query('POST', $arUrl['host'], $arUrl['port'], $arUrl['path_query'], $postdata, $arUrl['proto'], 'N', true); return true; } return false; } public function getServices() { return self::$pushServices; } static function _MakeJson($arData, $bWS, $bSkipTilda) { static $aSearch = array("\r", "\n"); if(is_array($arData)) { if($arData == array_values($arData)) { foreach($arData as $key => $value) { if(is_array($value)) { $arData[$key] = self::_MakeJson($value, $bWS, $bSkipTilda); } elseif(is_bool($value)) { if($value === true) $arData[$key] = "true"; else $arData[$key] = "false"; } elseif(is_integer($value)) { $res .= $value; } else { if(preg_match("#['\"\\n\\r<\\\\]#", $value)) $arData[$key] = "\"".CUtil::JSEscape($value)."\""; else $arData[$key] = "\"".$value."\""; } } return '['.implode(',', $arData).']'; } $sWS = ','.($bWS ? "\n" : ''); $res = ($bWS ? "\n" : '').'{'; $first = true; foreach($arData as $key => $value) { if ($bSkipTilda && substr($key, 0, 1) == '~') continue; if($first) $first = false; else $res .= $sWS; if(preg_match("#['\"\\n\\r<\\\\]#", $key)) $res .= "\"".str_replace($aSearch, '', CUtil::addslashes($key))."\":"; else $res .= "\"".$key."\":"; if(is_array($value)) { $res .= self::_MakeJson($value, $bWS, $bSkipTilda); } elseif(is_bool($value)) { if($value === true) $res .= "true"; else $res .= "false"; } elseif(is_integer($value)) { $res .= $value; } else { if(preg_match("#['\"\\n\\r<\\\\]#", $value)) $res .= "\"".CUtil::JSEscape($value)."\""; else $res .= "\"".$value."\""; } } $res .= ($bWS ? "\n" : '').'}'; return $res; } elseif(is_bool($arData)) { if($arData === true) return 'true'; else return 'false'; } elseif(is_integer($value)) { return $value; } else { if(preg_match("#['\"\\n\\r<\\\\]#", $arData)) return "\"".CUtil::JSEscape($arData)."'"; else return "\"".$arData."\""; } } } ?>