1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
access.php
См. документацию.
1<?php
8
11
12IncludeModuleLangFile(__FILE__);
13
15{
16 const CHECK_CACHE_DIR = "access_check";
17 const CACHE_DIR = "access_codes";
18
19 protected static $arAuthProviders = [];
20 protected static $arChecked = [];
21 protected static $userCodes = [];
22 protected $arParams = false;
23
24 public function __construct($arParams = false)
25 {
26 $this->arParams = $arParams;
27
28 if (empty(static::$arAuthProviders))
29 {
30 foreach (GetModuleEvents("main", "OnAuthProvidersBuildList", true) as $arEvent)
31 {
32 $res = ExecuteModuleEventEx($arEvent);
33 if (is_array($res))
34 {
35 if (!is_array($res[0]))
36 {
37 $res = [$res];
38 }
39 foreach ($res as $provider)
40 {
41 static::$arAuthProviders[$provider["ID"]] = $provider;
42 }
43 }
44 }
45 sortByColumn(static::$arAuthProviders, "SORT");
46 }
47 }
48
49 protected static function NeedToRecalculate($provider, $USER_ID, DateTime $now)
50 {
51 global $DB, $CACHE_MANAGER;
52
53 $USER_ID = intval($USER_ID);
54
55 if (!isset(static::$arChecked[$provider][$USER_ID]))
56 {
57 $cacheId = static::GetCheckCacheId($provider, $USER_ID);
58
59 if (CACHED_b_user_access_check !== false && $CACHE_MANAGER->Read(CACHED_b_user_access_check, $cacheId, static::CHECK_CACHE_DIR))
60 {
61 static::$arChecked[$provider][$USER_ID] = $CACHE_MANAGER->Get($cacheId);
62 }
63 else
64 {
65 $res = $DB->Query("
66 select DATE_CHECK
67 from b_user_access_check
68 where USER_ID = " . $USER_ID . "
69 and PROVIDER_ID = '" . $DB->ForSql($provider) . "'
70 ");
71
72 static::$arChecked[$provider][$USER_ID] = [];
73 while ($check = $res->Fetch())
74 {
75 static::$arChecked[$provider][$USER_ID][] = $check['DATE_CHECK'];
76 }
77
78 if (CACHED_b_user_access_check !== false)
79 {
80 $CACHE_MANAGER->Set($cacheId, static::$arChecked[$provider][$USER_ID]);
81 }
82 }
83 }
84
85 $helper = Main\Application::getConnection()->getSqlHelper();
86
87 foreach (static::$arChecked[$provider][$USER_ID] as $dateCheck)
88 {
89 $date = $helper->convertFromDbDateTime($dateCheck);
90 if ($date && $date->getTimestamp() <= $now->getTimestamp())
91 {
92 return true;
93 }
94 }
95
96 return false;
97 }
98
99 public function UpdateCodes($arParams = false)
100 {
101 global $USER;
102
103 $USER_ID = 0;
104 if (is_array($arParams) && isset($arParams["USER_ID"]))
105 {
106 $USER_ID = intval($arParams["USER_ID"]);
107 }
108 elseif (is_object($USER) && $USER->IsAuthorized())
109 {
110 $USER_ID = intval($USER->GetID());
111 }
112
113 if ($USER_ID > 0)
114 {
115 $connection = Main\Application::getConnection();
116 $clearCache = false;
117 $now = new DateTime();
118
119 foreach (static::$arAuthProviders as $providerId => $providerDescription)
120 {
122 $provider = new $providerDescription["CLASS"];
123
124 if (is_callable([$provider, "UpdateCodes"]))
125 {
126 //do we need to recalculate codes for the user?
127 if (static::NeedToRecalculate($providerId, $USER_ID, $now))
128 {
129 $lockName = "update_codes.{$providerId}.{$USER_ID}";
130
131 // we don't want to do the same job twice
132 if ($connection->lock($lockName))
133 {
134 $connection->startTransaction();
135
136 //should clear codes cache for the user
137 $clearCache = true;
138
139 //remove old codes
140 static::DeleteCodes($providerId, $USER_ID);
141
142 //call provider to insert access codes
143 $provider->UpdateCodes($USER_ID);
144
145 //update cache for checking
146 static::UpdateStat($providerId, $USER_ID, $now);
147
148 $connection->commitTransaction();
149 $connection->unlock($lockName);
150 }
151 }
152 }
153 }
154
155 if ($clearCache)
156 {
157 static::ClearCache($USER_ID);
158 }
159 }
160 }
161
167 public static function AddCode($userId, $provider, $code)
168 {
169 $userId = (int)$userId;
170
172 $helper = $connection->getSqlHelper();
173
174 $sql = $helper->getInsertIgnore(
175 'b_user_access',
176 '(USER_ID, PROVIDER_ID, ACCESS_CODE)',
177 "VALUES ({$userId}, '{$helper->forSql($provider)}', '{$helper->forSql($code)}')"
178 );
179
180 $connection->query($sql);
181
182 static::ClearCache($userId);
183 }
184
190 public static function RemoveCode($userId, $provider, $code)
191 {
192 $userId = (int)$userId;
193
195 $helper = $connection->getSqlHelper();
196
197 $connection->query("
198 DELETE FROM b_user_access
199 WHERE USER_ID = {$userId}
200 AND PROVIDER_ID = '{$helper->forSql($provider)}'
201 AND ACCESS_CODE = '{$helper->forSql($code)}'
202 ");
203
204 static::ClearCache($userId);
205 }
206
210 public static function ClearCache($userId)
211 {
212 global $CACHE_MANAGER;
213
214 $CACHE_MANAGER->Clean(static::GetCodesCacheId($userId), static::CACHE_DIR);
215 unset(static::$userCodes[$userId]);
216 }
217
218 public static function RecalculateForUser($userId, $provider, DateTime $dateCheck = null)
219 {
220 global $DB;
221
223 $helper = $connection->getSqlHelper();
224
225 $userId = intval($userId);
226
227 if ($dateCheck === null)
228 {
229 $dateCheck = new DateTime('1974-12-07', 'Y-m-d'); // somewhen in the past
230 }
231
232 $sql = $helper->getInsertIgnore('b_user_access_check', '(USER_ID, PROVIDER_ID, DATE_CHECK)', "
233 SELECT ID, '{$DB->ForSQL($provider)}', {$helper->convertToDbDateTime($dateCheck)}
234 FROM b_user
235 WHERE ID = {$userId}"
236 );
237 $connection->query($sql);
238
239 static::ClearCheckCache($provider, $userId);
240 }
241
242 public static function RecalculateForProvider($provider)
243 {
244 global $CACHE_MANAGER;
245
247 $helper = $connection->getSqlHelper();
248
249 $dateCheck = new DateTime('1974-12-07', 'Y-m-d'); // somewhen in the past
250
251 $sql = $helper->getInsertIgnore('b_user_access_check', '(USER_ID, PROVIDER_ID, DATE_CHECK)', "
252 SELECT USER_ID, PROVIDER_ID, {$helper->convertToDbDateTime($dateCheck)}
253 FROM b_user_access
254 WHERE PROVIDER_ID = '" . $helper->forSQL($provider) . "'
255 AND USER_ID > 0
256 GROUP BY USER_ID, PROVIDER_ID
257 ");
258 $connection->query($sql);
259
260 $CACHE_MANAGER->CleanDir(static::CHECK_CACHE_DIR);
261 unset(static::$arChecked[$provider]);
262 }
263
264 protected static function GetCheckCacheId($provider, $userId)
265 {
266 return "access_check_v2_" . $provider . "_" . $userId;
267 }
268
269 protected static function GetCodesCacheId($userId)
270 {
271 return "access_codes" . $userId;
272 }
273
274 protected static function DeleteCodes($providerId, $userId)
275 {
276 $userId = (int)$userId;
277
279 $helper = $connection->getSqlHelper();
280
281 $connection->query("
282 delete from b_user_access
283 where user_id = {$userId}
284 and provider_id = '{$helper->forSql($providerId)}'
285 ");
286 }
287
288 protected static function UpdateStat($provider, $userId, DateTime $now)
289 {
290 global $DB;
291
292 $userId = intval($userId);
293
294 $helper = Main\Application::getConnection()->getSqlHelper();
295
296 $DB->Query("
297 delete from b_user_access_check
298 where user_id = {$userId}
299 and provider_id = '{$DB->ForSql($provider)}'
300 and date_check <= {$helper->convertToDbDateTime($now)}
301 ");
302
303 static::ClearCheckCache($provider, $userId);
304 }
305
306 protected static function ClearCheckCache($provider, $userId)
307 {
308 global $CACHE_MANAGER;
309
310 $CACHE_MANAGER->Clean(static::GetCheckCacheId($provider, $userId), static::CHECK_CACHE_DIR);
311 unset(static::$arChecked[$provider][$userId]);
312 }
313
314 public static function GetUserCodes($USER_ID, $arFilter = [], bool $updateCodes = true)
315 {
316 global $DB;
317
318 if ($updateCodes)
319 {
320 $access = new CAccess();
321 $access->UpdateCodes(['USER_ID' => $USER_ID]);
322 }
323
324 $arWhere = [];
325 foreach ($arFilter as $key => $val)
326 {
327 $key = strtoupper($key);
328 switch ($key)
329 {
330 case "ACCESS_CODE":
331 if (!is_array($val))
332 {
333 $val = [$val];
334 }
335 $arIn = [];
336 foreach ($val as $code)
337 {
338 if (trim($code) <> '')
339 {
340 $arIn[] = "'" . $DB->ForSQL(trim($code)) . "'";
341 }
342 }
343 if (!empty($arIn))
344 {
345 $arWhere[] = "access_code in(" . implode(",", $arIn) . ")";
346 }
347 break;
348 case "PROVIDER_ID":
349 $arWhere[] = "provider_id='" . $DB->ForSQL($val) . "'";
350 break;
351 }
352 }
353
354 if (empty($arFilter))
355 {
356 // nobody wants chat codes and there are plenty of them
357 $arWhere[] = "provider_id <> 'imchat'";
358 }
359
360 $sWhere = '';
361 if (!empty($arWhere))
362 {
363 $sWhere = " and " . implode(" and ", $arWhere);
364 }
365
366 return $DB->Query("select * from b_user_access where user_id=" . intval($USER_ID) . $sWhere);
367 }
368
369 public static function GetUserCodesArray($USER_ID, $arFilter = [])
370 {
371 global $CACHE_MANAGER;
372
373 $USER_ID = intval($USER_ID);
374
375 $access = new CAccess();
376 $access->UpdateCodes(['USER_ID' => $USER_ID]);
377
378 if (empty($arFilter) && isset(static::$userCodes[$USER_ID]))
379 {
380 return static::$userCodes[$USER_ID];
381 }
382
383 $useCache = (empty($arFilter) && CACHED_b_user_access_check !== false);
384 $cacheId = static::GetCodesCacheId($USER_ID);
385
386 if ($useCache && $CACHE_MANAGER->Read(CACHED_b_user_access_check, $cacheId, static::CACHE_DIR))
387 {
388 $arCodes = $CACHE_MANAGER->Get($cacheId);
389 }
390 else
391 {
392 $arCodes = [];
393 $res = CAccess::GetUserCodes($USER_ID, $arFilter, false);
394 while ($arRes = $res->Fetch())
395 {
396 $arCodes[] = $arRes["ACCESS_CODE"];
397 }
398
399 if ($useCache)
400 {
401 $CACHE_MANAGER->Set($cacheId, $arCodes);
402 }
403 }
404
405 if (empty($arFilter))
406 {
407 static::$userCodes[$USER_ID] = $arCodes;
408 }
409
410 return $arCodes;
411 }
412
413 public function GetFormHtml()
414 {
415 $arHtml = [];
416 foreach (static::$arAuthProviders as $provider)
417 {
418 $cl = new $provider["CLASS"];
419 if (is_callable([$cl, "GetFormHtml"]))
420 {
421 $res = call_user_func_array([$cl, "GetFormHtml"], [$this->arParams]);
422 if ($res !== false)
423 {
424 $arHtml[$provider["ID"]] = [
425 "NAME" => $provider["NAME"],
426 "HTML" => $res["HTML"],
427 "SELECTED" => $res["SELECTED"] ?? false,
428 ];
429 }
430 }
431 }
432 return $arHtml;
433 }
434
435 public function AjaxRequest($arParams)
436 {
437 if (isset(static::$arAuthProviders[$arParams["provider"]]))
438 {
439 $cl = new static::$arAuthProviders[$arParams["provider"]]["CLASS"];
440 if (is_callable([$cl, "AjaxRequest"]))
441 {
442 return call_user_func_array([$cl, "AjaxRequest"], [$this->arParams]);
443 }
444 }
445 return false;
446 }
447
448 public function GetNames($arCodes, $bSort = false)
449 {
450 $arResult = [];
451
452 if (!is_array($arCodes) || empty($arCodes))
453 {
454 return $arResult;
455 }
456
457 foreach (static::$arAuthProviders as $provider)
458 {
459 $cl = new $provider["CLASS"];
460 if (is_callable([$cl, "GetNames"]))
461 {
462 $res = call_user_func_array([$cl, "GetNames"], [$arCodes]);
463 if (is_array($res))
464 {
465 foreach ($res as $codeId => $codeValues)
466 {
467 $codeValues['provider_id'] = $provider['ID'];
468 $arResult[$codeId] = $codeValues;
469 }
470 }
471 }
472 }
473
474 if ($bSort)
475 {
476 uasort($arResult, ['CAccess', 'CmpNames']);
477 }
478
479 return $arResult;
480 }
481
482 public static function CmpNames($a, $b)
483 {
484 $c = strcmp($a["provider"], $b["provider"]);
485 if ($c <> 0)
486 {
487 return $c;
488 }
489
490 return strcmp($a["name"], $b["name"]);
491 }
492
493 public function GetProviderNames()
494 {
495 $arResult = [];
496 foreach (static::$arAuthProviders as $ID => $provider)
497 {
498 $arResult[$ID] = [
499 "name" => ($provider["PROVIDER_NAME"] ?? $ID),
500 "prefixes" => ($provider["PREFIXES"] ?? []),
501 ];
502 }
503 return $arResult;
504 }
505
506 public static function GetProviders()
507 {
508 return [
509 [
510 "ID" => "group",
511 "NAME" => GetMessage("access_groups"),
512 "PROVIDER_NAME" => GetMessage("access_group"),
513 "SORT" => 100,
514 "CLASS" => "CGroupAuthProvider",
515 ],
516 [
517 "ID" => "user",
518 "NAME" => GetMessage("access_users"),
519 "PROVIDER_NAME" => GetMessage("access_user"),
520 "SORT" => 200,
521 "CLASS" => "CUserAuthProvider",
522 ],
523 [
524 "ID" => "other",
525 "NAME" => GetMessage("access_other"),
526 "PROVIDER_NAME" => "",
527 "SORT" => 1000,
528 "CLASS" => "COtherAuthProvider",
529 ],
530 ];
531 }
532
533 public static function OnUserDelete($USER_ID)
534 {
535 global $DB;
536 $USER_ID = intval($USER_ID);
537
538 $DB->Query("delete from b_user_access where user_id=" . $USER_ID);
539 $DB->Query("delete from b_user_access_check where user_id=" . $USER_ID);
540
541 //all providers for one user
542 foreach (static::$arChecked as $provider => $dummy)
543 {
544 static::ClearCheckCache($provider, $USER_ID);
545 }
546
547 static::ClearCache($USER_ID);
548
549 return true;
550 }
551
552 public static function SaveLastRecentlyUsed($arLRU)
553 {
554 foreach ($arLRU as $provider => $arRecent)
555 {
556 if (is_array($arRecent))
557 {
558 $arLastRecent = CUserOptions::GetOption("access_dialog_recent", $provider, []);
559
560 $arItems = array_keys($arRecent);
561 $arItems = array_unique(array_merge($arItems, $arLastRecent));
562 $arItems = array_slice($arItems, 0, 20);
563
564 CUserOptions::SetOption("access_dialog_recent", $provider, $arItems);
565 }
566 }
567 }
568
569 public static function GetLastRecentlyUsed($provider)
570 {
571 $res = CUserOptions::GetOption("access_dialog_recent", $provider, []);
572 if (!is_array($res))
573 {
574 $res = [];
575 }
576 return $res;
577 }
578
584 public static function deleteDuplicatesAgent(int $lastId = 0)
585 {
587
588 if (!($connection instanceof Main\DB\MysqlCommonConnection))
589 {
590 return '';
591 }
592
593 if ($connection->getIndexName('b_user_access', ['USER_ID', 'ACCESS_CODE'], true) === 'ux_ua_user_access')
594 {
595 return '';
596 }
597
598 $codes = $connection->query("
599 select ID, USER_ID, ACCESS_CODE
600 from b_user_access
601 where ID > {$lastId}
602 order by ID
603 limit 10000
604 ");
605
606 $id = null;
607 while ($code = $codes->fetch())
608 {
609 $id = $code['ID'];
610
611 $connection->query("
612 delete from b_user_access
613 where ID > {$id}
614 and USER_ID = {$code['USER_ID']}
615 and ACCESS_CODE = '{$code['ACCESS_CODE']}'
616 ");
617 }
618
619 if ($id !== null)
620 {
621 return "CAccess::deleteDuplicatesAgent({$id});";
622 }
623
624 try
625 {
626 $connection->query("
627 alter table b_user_access
628 drop index ix_ua_user_access,
629 add UNIQUE INDEX ux_ua_user_access (USER_ID, ACCESS_CODE)
630 ");
631 }
632 catch (Main\DB\SqlQueryException)
633 {
634 return "CAccess::deleteDuplicatesAgent();";
635 }
636
637 return '';
638 }
639}
640
641AddEventHandler("main", "OnAuthProvidersBuildList", ["CAccess", "GetProviders"]);
$arHtml
Определения access_dialog.php:55
$arParams
Определения access_dialog.php:21
$connection
Определения actionsdefinitions.php:38
if(!Loader::includeModule('messageservice')) $provider
Определения callback_ednaruimhpx.php:21
$arResult
Определения generate_coupon.php:16
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getConnection($name="")
Определения application.php:638
getTimestamp()
Определения date.php:218
Определения access.php:15
static $arChecked
Определения access.php:20
static RecalculateForUser($userId, $provider, DateTime $dateCheck=null)
Определения access.php:218
static UpdateStat($provider, $userId, DateTime $now)
Определения access.php:288
static GetProviders()
Определения access.php:506
static ClearCheckCache($provider, $userId)
Определения access.php:306
static RemoveCode($userId, $provider, $code)
Определения access.php:190
$arParams
Определения access.php:22
static DeleteCodes($providerId, $userId)
Определения access.php:274
static GetLastRecentlyUsed($provider)
Определения access.php:569
static OnUserDelete($USER_ID)
Определения access.php:533
GetNames($arCodes, $bSort=false)
Определения access.php:448
static $userCodes
Определения access.php:21
static $arAuthProviders
Определения access.php:19
static GetCodesCacheId($userId)
Определения access.php:269
static RecalculateForProvider($provider)
Определения access.php:242
GetFormHtml()
Определения access.php:413
GetProviderNames()
Определения access.php:493
static NeedToRecalculate($provider, $USER_ID, DateTime $now)
Определения access.php:49
static GetUserCodesArray($USER_ID, $arFilter=[])
Определения access.php:369
static AddCode($userId, $provider, $code)
Определения access.php:167
static GetUserCodes($USER_ID, $arFilter=[], bool $updateCodes=true)
Определения access.php:314
const CACHE_DIR
Определения access.php:17
static SaveLastRecentlyUsed($arLRU)
Определения access.php:552
AjaxRequest($arParams)
Определения access.php:435
const CHECK_CACHE_DIR
Определения access.php:16
__construct($arParams=false)
Определения access.php:24
static deleteDuplicatesAgent(int $lastId=0)
Определения access.php:584
static GetCheckCacheId($provider, $userId)
Определения access.php:264
static ClearCache($userId)
Определения access.php:210
static CmpNames($a, $b)
Определения access.php:482
global $CACHE_MANAGER
Определения clear_component_cache.php:7
if(!\Bitrix\Main\Loader::includeModule('clouds')) $lastId
Определения sync.php:68
$res
Определения filter_act.php:7
if($ajaxMode) $ID
Определения get_user.php:27
global $DB
Определения cron_frame.php:29
global $USER
Определения csv_new_run.php:40
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
if(!is_array($deviceNotifyCodes)) $access
Определения options.php:174
$arCodes
Определения options.php:154
ExecuteModuleEventEx($arEvent, $arParams=[])
Определения tools.php:5214
AddEventHandler($FROM_MODULE_ID, $MESSAGE_ID, $CALLBACK, $SORT=100, $FULL_PATH=false)
Определения tools.php:5165
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
Определения tools.php:5177
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
GetMessage($name, $aReplace=null)
Определения tools.php:3397
sortByColumn(array &$array, $columns, $callbacks='', $defaultValueIfNotSetValue=null, $preserveKeys=false)
Определения tools.php:5087
Определения arrayresult.php:2
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
else $a
Определения template.php:137
$val
Определения options.php:1793
$clearCache
Определения seo_client.php:21
$arRes
Определения options.php:104
$arFilter
Определения user_search.php:106