portal.mkgtu.ru/common/components/soapClientManager.php

296 lines
9.0 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace common\components;
use common\models\DebuggingSoap;
use common\models\DummySoapResponse;
use common\models\EmptyCheck;
use SoapClient;
use Yii;
use yii\caching\CacheInterface;
use yii\caching\Dependency;
use yii\caching\TagDependency;
class soapClientManager extends \yii\base\Component
{
public $wsdl;
public $login;
public $debug;
public $password;
public $client;
protected ?int $user_id;
protected CacheInterface $cache;
protected bool $use_real_cache;
protected array $local_cache = [];
public function __construct(CacheInterface $cache, $config = [])
{
parent::__construct($config);
$this->cache = $cache;
$this->use_real_cache = BooleanCaster::cast(getenv('ENABLE_QUERY_CACHE'));
if (isset(Yii::$app->user)) {
if (Yii::$app->user->isGuest) {
$this->user_id = null;
} else {
$this->user_id = (int)Yii::$app->user->id;
}
} else {
$this->user_id = 1;
}
}
public function init()
{
parent::init();
if (!str_starts_with($this->wsdl, 'http')) {
return;
}
try {
ini_set("soap.wsdl_cache_enabled", 0);
$current_default_socket_timeout = ini_get('default_socket_timeout');
if ($current_default_socket_timeout < 600) {
ini_set('default_socket_timeout', 600);
}
$this->client = new SoapClient($this->wsdl, [
'login' => $this->login,
'password' => $this->password,
'keep_alive' => BooleanCaster::cast(getenv('SOAP_KEEP_ALIVE')),
'trace' => false,
'exceptions' => true,
'cache_wsdl' => WSDL_CACHE_NONE,
'location' => strstr($this->wsdl, '?', true),
'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | SOAP_COMPRESSION_DEFLATE,
]);
} catch (\Throwable $e) {
Yii::$app->session->setFlash(
'UnsuccessfulConnectionWithSoap',
'<strong>Невозможно подключиться к веб-сервисам Информационной системы вуза:</strong> ' . $e->getMessage()
);
throw new \yii\base\UserException('Документ WSDL недоступен или некорректен.', '11001', $e);
}
}
public function getIsInitialized(): bool
{
return isset($this->client);
}
public function isServicesEnabled(): bool
{
if (!$this->isInitialized) {
return false;
}
$env = getenv('ENABLE_1C_SERVICES') !== false ? getenv('ENABLE_1C_SERVICES') : 'true';
return $env === 'true';
}
public function load($action, $params = [], bool $write_logs = true)
{
$enable1cServices = $this->isServicesEnabled();
if (!$enable1cServices) {
return false;
}
$debuggingEnabled = false;
$dummySoapEnable = false;
$loggers = [];
try {
$model = DebuggingSoap::getInstance();
$debuggingEnabled = ($model->debugging_enable || $model->xml_debugging_enable);
$dummySoapEnable = $model->enable_dummy_soap_mode;
$loggers = $model->getEnabledLoggers();
} catch (\Throwable $e) {
$debuggingEnabled = false;
$loggers = [];
Yii::error('Не установлена таблица "debuggingsoap"');
}
$dummyResponse = null;
if ($dummySoapEnable) {
$dummyResponse = DummySoapResponse::find()->where(['method_name' => $action])->limit(1)->one();
if (!empty($dummyResponse)) {
$data_from_xml = simplexml_load_string($dummyResponse->method_response);
if (!empty($data_from_xml)) {
$array_data = json_decode(json_encode($data_from_xml), true);
$array_data = $this->processJsonArray($array_data);
if ($array_data == "") {
return false;
}
return json_decode(json_encode($array_data));
}
}
}
$startTime = date(DATE_ATOM);
try {
$buffer = false;
if ($this->client != null) {
if (is_string($params)) {
$buffer = $this->client->$action(new \SoapVar(trim((string)$params), XSD_ANYXML));
} else {
$buffer = $this->client->$action($params);
}
}
if ($debuggingEnabled && $write_logs) {
$endTime = date(DATE_ATOM);
foreach ($loggers as $logger) {
$logger->doRequestLog($action, $startTime, $endTime, $params, $buffer);
}
}
return $buffer;
} catch (\Throwable $e) {
foreach ($loggers as $logger) {
$logger->doErrorLog($action, $startTime, $params, $e);
}
throw new soapException(
'Ошибка обращения к методу.',
'11002',
$action,
$e->getMessage(),
$params
);
}
}
public function resetCurrentUserCache(string $action, array $additional_user_ids_to_clear_cache = [])
{
if ($this->use_real_cache) {
foreach ($additional_user_ids_to_clear_cache as $additional_user_id) {
TagDependency::invalidate($this->cache, $action . '.' . $additional_user_id);
}
if (!$this->user_id) {
return;
}
if (!in_array($this->user_id, $additional_user_ids_to_clear_cache)) {
TagDependency::invalidate($this->cache, $action . '.' . $this->user_id);
}
} else {
foreach (array_keys($this->local_cache) as $key) {
if (str_starts_with($key, $action)) {
unset($this->local_cache[$key]);
}
}
}
}
public function load_with_caching(string $action, $params = [], bool $write_logs = true)
{
$sorted_params = null;
if (!is_string($params)) {
$sorted_params = json_decode(json_encode($params), true);
$this->recursive_ksort($sorted_params);
} else {
$sorted_params = $params;
}
$params_key = md5(json_encode($sorted_params));
$cache_key = $action . '_' . $params_key;
if ($this->cacheExists($cache_key)) {
return $this->cacheGet($cache_key);
}
$result = $this->load($action, $params, $write_logs);
if ($result) {
$this->cacheSet($cache_key, $result, 120, new TagDependency(['tags' => [$action, $action . '.' . $this->user_id]]));
}
return $result;
}
protected function cacheExists(string $cache_key): bool
{
if ($this->use_real_cache) {
return $this->cache->exists($cache_key);
} else {
return isset($this->local_cache[$cache_key]);
}
}
protected function cacheGet(string $cache_key)
{
if ($this->use_real_cache) {
return $this->cache->get($cache_key);
} else {
return $this->local_cache[$cache_key] ?? null;
}
}
protected function cacheSet(string $cache_key, $value, int $duration, Dependency $dependency = null)
{
if ($this->use_real_cache) {
$this->cache->set($cache_key, $value, $duration, $dependency);
} else {
$this->local_cache[$cache_key] = $value;
}
}
protected function recursive_ksort(&$array)
{
foreach ($array as $k => &$v) {
if (is_array($v)) {
$this->recursive_ksort($v);
}
}
return ksort($array);
}
protected function processJsonArray($array_to_convert)
{
if (empty($array_to_convert)) {
return "";
}
$is_empty_array = true;
foreach ($array_to_convert as &$item) {
if (is_array($item)) {
$item = $this->processJsonArray($item);
if ($item !== "") {
$is_empty_array = false;
}
} else {
if ($item === 'true') {
$item = true;
$is_empty_array = false;
} elseif ($item === 'false') {
$item = false;
$is_empty_array = false;
} else {
$item = trim((string)$item);
if ($item || !EmptyCheck::isEmpty($item)) {
$is_empty_array = false;
}
}
}
}
if ($is_empty_array) {
return "";
}
return $array_to_convert;
}
}