PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/main/classes/general/agent.php

https://gitlab.com/alexprowars/bitrix
PHP | 338 lines | 283 code | 45 blank | 10 comment | 55 complexity | 37a95479285cd192d9cdb9ca84ab1389 MD5 | raw file
  1. <?php
  2. /**
  3. * Bitrix Framework
  4. * @package bitrix
  5. * @subpackage main
  6. * @copyright 2001-2013 Bitrix
  7. */
  8. use Bitrix\Main\Localization\Loc;
  9. Loc::loadMessages(__FILE__);
  10. class CAllAgent
  11. {
  12. public static function AddAgent(
  13. $name, // PHP function name
  14. $module = "", // module
  15. $period = "N", // check for agent execution count in period of time
  16. $interval = 86400, // time interval between execution
  17. $datecheck = "", // first check for execution time
  18. $active = "Y", // is the agent active or not
  19. $next_exec = "", // first execution time
  20. $sort = 100, // order
  21. $user_id = false, // user
  22. $existError = true // return error, if agent already exist
  23. )
  24. {
  25. global $DB, $APPLICATION;
  26. $z = $DB->Query("
  27. SELECT ID
  28. FROM b_agent
  29. WHERE NAME = '".$DB->ForSql($name)."'
  30. AND USER_ID".($user_id? " = ".(int)$user_id: " IS NULL")
  31. );
  32. if (!($agent = $z->Fetch()))
  33. {
  34. $arFields = array(
  35. "MODULE_ID" => $module,
  36. "SORT" => $sort,
  37. "NAME" => $name,
  38. "ACTIVE" => $active,
  39. "AGENT_INTERVAL" => $interval,
  40. "IS_PERIOD" => $period,
  41. "USER_ID" => $user_id,
  42. );
  43. $next_exec = (string)$next_exec;
  44. if ($next_exec != '')
  45. $arFields["NEXT_EXEC"] = $next_exec;
  46. $ID = CAgent::Add($arFields);
  47. return $ID;
  48. }
  49. else
  50. {
  51. if (!$existError)
  52. return $agent['ID'];
  53. $e = new CAdminException(array(
  54. array(
  55. "id" => "agent_exist",
  56. "text" => ($user_id
  57. ? Loc::getMessage("MAIN_AGENT_ERROR_EXIST_FOR_USER", array('#AGENT#' => $name, '#USER_ID#' => $user_id))
  58. : Loc::getMessage("MAIN_AGENT_ERROR_EXIST_EXT", array('#AGENT#' => $name))
  59. )
  60. )
  61. ));
  62. $APPLICATION->throwException($e);
  63. return false;
  64. }
  65. }
  66. public static function Add($arFields)
  67. {
  68. global $DB, $CACHE_MANAGER;
  69. if (CAgent::CheckFields($arFields))
  70. {
  71. if (!is_set($arFields, "NEXT_EXEC"))
  72. $arFields["~NEXT_EXEC"] = $DB->GetNowDate();
  73. if (CACHED_b_agent !== false)
  74. $CACHE_MANAGER->CleanDir("agents");
  75. $ID = $DB->Add("b_agent", $arFields);
  76. foreach (GetModuleEvents("main", "OnAfterAgentAdd", true) as $arEvent)
  77. ExecuteModuleEventEx($arEvent, array(
  78. $arFields,
  79. ));
  80. return $ID;
  81. }
  82. return false;
  83. }
  84. public static function RemoveAgent($name, $module = "", $user_id = false)
  85. {
  86. global $DB;
  87. if (trim($module) == '')
  88. $module = "AND (MODULE_ID is null or ".$DB->Length("MODULE_ID")." = 0)";
  89. else
  90. $module = "AND MODULE_ID = '".$DB->ForSql($module, 50)."'";
  91. $strSql = "
  92. DELETE FROM b_agent
  93. WHERE NAME = '".$DB->ForSql($name)."'
  94. ".$module."
  95. AND USER_ID".($user_id ? " = ".(int)$user_id : " IS NULL");
  96. $DB->Query($strSql, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__);
  97. }
  98. public static function Delete($id)
  99. {
  100. global $DB;
  101. $id = intval($id);
  102. if ($id <= 0)
  103. return false;
  104. $DB->Query("DELETE FROM b_agent WHERE ID = ".$id, false, "FILE: ".__FILE__."<br>LINE: ");
  105. return true;
  106. }
  107. public static function RemoveModuleAgents($module)
  108. {
  109. global $DB;
  110. if ($module <> '')
  111. {
  112. $strSql = "DELETE FROM b_agent WHERE MODULE_ID='".$DB->ForSql($module,255)."'";
  113. $DB->Query($strSql, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__);
  114. }
  115. }
  116. public static function Update($ID, $arFields)
  117. {
  118. global $DB, $CACHE_MANAGER;
  119. $ign_name = false;
  120. $ID = intval($ID);
  121. if(is_set($arFields, "ACTIVE") && $arFields["ACTIVE"]!="Y")
  122. $arFields["ACTIVE"]="N";
  123. if(is_set($arFields, "IS_PERIOD") && $arFields["IS_PERIOD"]!="Y")
  124. $arFields["IS_PERIOD"]="N";
  125. if(!is_set($arFields, "NAME"))
  126. $ign_name = true;
  127. if(CAgent::CheckFields($arFields, $ign_name))
  128. {
  129. if(CACHED_b_agent !== false)
  130. $CACHE_MANAGER->CleanDir("agents");
  131. $strUpdate = $DB->PrepareUpdate("b_agent", $arFields);
  132. $strSql = "UPDATE b_agent SET ".$strUpdate." WHERE ID=".$ID;
  133. $res = $DB->Query($strSql, false, "FILE: ".__FILE__."<br> LINE: ".__LINE__);
  134. return $res;
  135. }
  136. return false;
  137. }
  138. public static function GetById($ID)
  139. {
  140. return CAgent::GetList(Array(), Array("ID"=>intval($ID)));
  141. }
  142. public static function GetList($arOrder = Array("ID" => "DESC"), $arFilter = array())
  143. {
  144. global $DB;
  145. $err_mess = "FILE: ".__FILE__."<br>LINE: ";
  146. $arSqlSearch = array();
  147. $arSqlOrder = array();
  148. $arOFields = array(
  149. "ID" => "A.ID",
  150. "ACTIVE" => "A.ACTIVE",
  151. "IS_PERIOD" => "A.IS_PERIOD",
  152. "NAME" => "A.NAME",
  153. "MODULE_ID" => "A.MODULE_ID",
  154. "USER_ID" => "A.USER_ID",
  155. "LAST_EXEC" => "A.LAST_EXEC",
  156. "AGENT_INTERVAL" => "A.AGENT_INTERVAL",
  157. "NEXT_EXEC" => "A.NEXT_EXEC",
  158. "DATE_CHECK" => "A.DATE_CHECK",
  159. "SORT" => "A.SORT"
  160. );
  161. if(!is_array($arFilter))
  162. $filter_keys = array();
  163. else
  164. $filter_keys = array_keys($arFilter);
  165. for($i = 0, $n = count($filter_keys); $i < $n; $i++)
  166. {
  167. $val = $arFilter[$filter_keys[$i]];
  168. $key = mb_strtoupper($filter_keys[$i]);
  169. if((string)$val == '' || ($key=="USER_ID" && $val!==false && $val!==null))
  170. continue;
  171. switch($key)
  172. {
  173. case "ID":
  174. $arSqlSearch[] = "A.ID=".(int)$val;
  175. break;
  176. case "ACTIVE":
  177. $t_val = mb_strtoupper($val);
  178. if($t_val == "Y" || $t_val == "N")
  179. $arSqlSearch[] = "A.ACTIVE='".$t_val."'";
  180. break;
  181. case "IS_PERIOD":
  182. $t_val = mb_strtoupper($val);
  183. if($t_val=="Y" || $t_val=="N")
  184. $arSqlSearch[] = "A.IS_PERIOD='".$t_val."'";
  185. break;
  186. case "NAME":
  187. $arSqlSearch[] = "A.NAME LIKE '".$DB->ForSQLLike($val)."'";
  188. break;
  189. case "=NAME":
  190. $arSqlSearch[] = "A.NAME = '".$DB->ForSQL($val)."'";
  191. break;
  192. case "MODULE_ID":
  193. $arSqlSearch[] = "A.MODULE_ID = '".$DB->ForSQL($val)."'";
  194. break;
  195. case "USER_ID":
  196. $arSqlSearch[] = "A.USER_ID ".(intval($val)<=0?"IS NULL":"=".intval($val));
  197. break;
  198. case "LAST_EXEC":
  199. $arr = ParseDateTime($val, CLang::GetDateFormat());
  200. if($arr)
  201. {
  202. $date2 = mktime(0, 0, 0, $arr["MM"], $arr["DD"]+1, $arr["YYYY"]);
  203. $arSqlSearch[] = "A.LAST_EXEC>=".$DB->CharToDateFunction($DB->ForSql($val), "SHORT")." AND A.LAST_EXEC<".$DB->CharToDateFunction(ConvertTimeStamp($date2), "SHORT");
  204. }
  205. break;
  206. case "NEXT_EXEC":
  207. $arr = ParseDateTime($val);
  208. if($arr)
  209. {
  210. $date2 = mktime(0, 0, 0, $arr["MM"], $arr["DD"]+1, $arr["YYYY"]);
  211. $arSqlSearch[] = "A.NEXT_EXEC>=".$DB->CharToDateFunction($DB->ForSql($val), "SHORT")." AND A.NEXT_EXEC<".$DB->CharToDateFunction(ConvertTimeStamp($date2), "SHORT");
  212. }
  213. break;
  214. }
  215. }
  216. foreach($arOrder as $by => $order)
  217. {
  218. $by = mb_strtoupper($by);
  219. $order = mb_strtoupper($order);
  220. if (isset($arOFields[$by]))
  221. {
  222. if ($order != "ASC")
  223. $order = "DESC";
  224. else
  225. $order = "ASC";
  226. $arSqlOrder[] = $arOFields[$by]." ".$order;
  227. }
  228. }
  229. $strSql = "SELECT A.ID, A.MODULE_ID, A.USER_ID, B.LOGIN, B.NAME as USER_NAME, B.LAST_NAME, A.SORT, ".
  230. "A.NAME, A.ACTIVE, A.RUNNING, ".
  231. $DB->DateToCharFunction("A.LAST_EXEC")." as LAST_EXEC, ".
  232. $DB->DateToCharFunction("A.NEXT_EXEC")." as NEXT_EXEC, ".
  233. $DB->DateToCharFunction("A.DATE_CHECK")." as DATE_CHECK, ".
  234. "A.AGENT_INTERVAL, A.IS_PERIOD, A.RETRY_COUNT ".
  235. "FROM b_agent A LEFT JOIN b_user B ON(A.USER_ID = B.ID)";
  236. $strSql .= (count($arSqlSearch)>0) ? " WHERE ".implode(" AND ", $arSqlSearch) : "";
  237. $strSql .= (count($arSqlOrder)>0) ? " ORDER BY ".implode(", ", $arSqlOrder) : "";
  238. $res = $DB->Query($strSql, false, $err_mess.__LINE__);
  239. return $res;
  240. }
  241. public static function CheckFields(&$arFields, $ign_name = false)
  242. {
  243. global $DB, $APPLICATION;
  244. $errMsg = array();
  245. if(!$ign_name && (!is_set($arFields, "NAME") || mb_strlen(trim($arFields["NAME"])) <= 2))
  246. $errMsg[] = array("id" => "NAME", "text" => Loc::getMessage("MAIN_AGENT_ERROR_NAME"));
  247. if(
  248. array_key_exists("NEXT_EXEC", $arFields)
  249. && (
  250. $arFields["NEXT_EXEC"] == ""
  251. || !$DB->IsDate($arFields["NEXT_EXEC"], false, false, "FULL")
  252. )
  253. )
  254. {
  255. $errMsg[] = array("id" => "NEXT_EXEC", "text" => Loc::getMessage("MAIN_AGENT_ERROR_NEXT_EXEC"));
  256. }
  257. if(
  258. array_key_exists("DATE_CHECK", $arFields)
  259. && $arFields["DATE_CHECK"] <> ""
  260. && !$DB->IsDate($arFields["DATE_CHECK"], false, false, "FULL")
  261. )
  262. {
  263. $errMsg[] = array("id" => "DATE_CHECK", "text" => Loc::getMessage("MAIN_AGENT_ERROR_DATE_CHECK"));
  264. }
  265. if(
  266. array_key_exists("LAST_EXEC", $arFields)
  267. && $arFields["LAST_EXEC"] <> ""
  268. && !$DB->IsDate($arFields["LAST_EXEC"], false, false, "FULL")
  269. )
  270. {
  271. $errMsg[] = array("id" => "LAST_EXEC", "text" => Loc::getMessage("MAIN_AGENT_ERROR_LAST_EXEC"));
  272. }
  273. if(!empty($errMsg))
  274. {
  275. $e = new CAdminException($errMsg);
  276. $APPLICATION->ThrowException($e);
  277. return false;
  278. }
  279. return true;
  280. }
  281. /**
  282. * Three states: no cron (null), on cron (true), on hit (false).
  283. * @return bool|null
  284. */
  285. protected static function OnCron()
  286. {
  287. if (COption::GetOptionString('main', 'agents_use_crontab', 'N') == 'Y' || (defined('BX_CRONTAB_SUPPORT') && BX_CRONTAB_SUPPORT === true))
  288. {
  289. return (defined('BX_CRONTAB') && BX_CRONTAB === true);
  290. }
  291. return null;
  292. }
  293. }