Joywork/engine/classes/BiAnalytics.php

184 lines
6.2 KiB
PHP
Raw Permalink Normal View History

2026-07-15 15:33:08 +02:00
<?php
class BiAnalytics
{
private $supersetDomain;
private $loginEndpoint;
private $guestTokenEndpoint;
private $adminUsername;
private $adminPassword;
public function __construct()
{
$this->supersetDomain = trim('http://10.91.76.110');
$this->loginEndpoint = $this->supersetDomain . '/api/v1/security/login';
$this->guestTokenEndpoint = $this->supersetDomain . '/api/v1/security/guest_token/';
$this->adminUsername = 'admin';
$this->adminPassword = '6a6a78543e215c5adce1b828c9a30ef5';
}
public static function getAvailableUserIds($userId, $role)
{
if ($role === 'company_head') {
return null;
}
if ($role === 'agent') {
return array($userId);
}
if ($role === 'manager') {
$subordinates = self::getAllSubordinateIds($userId);
$subordinates[] = $userId;
return array_unique($subordinates);
}
return array($userId);
}
private static function getAllSubordinateIds($managerId)
{
$sql = "SELECT id FROM users WHERE id_manager = " . intval($managerId) . " AND blocked = 0";
$result = mysql_query($sql);
if (!$result) {
return array();
}
$subIds = array();
while ($row = mysql_fetch_assoc($result)) {
$subId = (int)$row['id'];
$subIds[] = $subId;
$subSubIds = self::getAllSubordinateIds($subId);
$subIds = array_merge($subIds, $subSubIds);
}
return $subIds;
}
public static function buildRlsRules($companyId, $userId, $role)
{
$tables = array(
'cur.clients_base',
'bi.client_kpi_daily',
'logs.client_events',
'cur.requisitions_base',
'bi.requisition_kpi_daily',
'logs.requisition_events'
);
$availableUserIds = self::getAvailableUserIds($userId, $role);
$rules = array();
// Одно правило company_id на все таблицы (без dataset_name — Superset применит ко всем)
$rules[] = array(
'clause' => "company_id = {$companyId}"
);
// Если не company_head — добавляем фильтр по who_work
if ($availableUserIds !== null) {
$userIdsString = implode(',', $availableUserIds);
$rules[] = array(
'clause' => "(who_work IN ({$userIdsString}) OR who_work = 0)"
);
}
return $rules;
}
public function getGuestToken($dashboardUuid, $companyId, $userId, $userRole, $userInfo = array())
{
try {
$accessToken = $this->getAdminAccessToken();
if (!$accessToken) {
return array('error' => 'Failed to obtain admin access token');
}
$rlsRules = self::buildRlsRules($companyId, $userId, $userRole);
$guestTokenData = array(
'resources' => array(
array(
'type' => 'dashboard',
'id' => $dashboardUuid
)
),
'rls' => $rlsRules,
'ui_config' => array(
'show_sql' => in_array($userRole, array('manager', 'company_head', 'admin', 'agent')),
'url_params' => array(
'filter_company_id' => (string)$companyId
)
),
'user' => array(
'username' => 'joywork_user_' . $userId,
'first_name' => isset($userInfo['first_name']) ? $userInfo['first_name'] : 'User',
'last_name' => isset($userInfo['last_name']) ? $userInfo['last_name'] : (string)$userId,
'email' => isset($userInfo['email']) ? $userInfo['email'] : null,
),
'attributes' => array(
'company_id' => $companyId,
'available_user_ids' => self::getAvailableUserIds($userId, $userRole),
),
);
$response = $this->makeRequest($this->guestTokenEndpoint, $guestTokenData, $accessToken);
if (isset($response['token'])) {
return array('token' => $response['token']);
} else {
return array('error' => 'Guest token not returned', 'details' => $response);
}
} catch (Exception $e) {
return array('error' => $e->getMessage());
}
}
private function getAdminAccessToken()
{
$loginData = array(
'username' => $this->adminUsername,
'password' => $this->adminPassword,
'provider' => 'db',
'refresh' => true,
);
$response = $this->makeRequest($this->loginEndpoint, $loginData);
if (isset($response['access_token'])) {
return $response['access_token'];
}
return null;
}
private function makeRequest($url, $postData, $accessToken = null)
{
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($postData),
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Accept: application/json',
),
CURLOPT_SSL_VERIFYPEER => false,
));
if ($accessToken) {
$headers = array(
'Content-Type: application/json',
'Accept: application/json',
'Authorization: Bearer ' . $accessToken,
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$responseBody = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("API request failed. HTTP code: $httpCode. Response: $responseBody");
}
$decoded = json_decode($responseBody, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new Exception("Invalid JSON response: " . json_last_error_msg());
}
return $decoded;
}
}