458 lines
10 KiB
PHP
458 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* Bitrix Framework
|
|
* @package bitrix
|
|
* @subpackage seo
|
|
* @copyright 2001-2013 Bitrix
|
|
*/
|
|
|
|
namespace Bitrix\Seo;
|
|
|
|
use Bitrix\Main\Application;
|
|
use Bitrix\Main\Context;
|
|
use Bitrix\Main\Loader;
|
|
use Bitrix\Main\LoaderException;
|
|
use Bitrix\Main\Localization\Loc;
|
|
use Bitrix\Main\SystemException;
|
|
use Bitrix\Main\Web\HttpClient;
|
|
use Bitrix\Main\Web\Json;
|
|
use Bitrix\Seo\Engine\Bitrix;
|
|
use Bitrix\Seo\Retargeting\AdsAudience;
|
|
use Bitrix\Seo\Retargeting\Request;
|
|
|
|
Loc::loadMessages(__FILE__);
|
|
|
|
if (!defined("BITRIX_CLOUD_ADV_URL"))
|
|
{
|
|
$domain = (new \Bitrix\Main\License\UrlProvider())->getTechDomain();
|
|
$cloudAdvUrl = 'https://cloud-adv.' . $domain;
|
|
|
|
define("BITRIX_CLOUD_ADV_URL", $cloudAdvUrl);
|
|
}
|
|
|
|
if (!defined("SEO_SERVICE_URL"))
|
|
{
|
|
define('SEO_SERVICE_URL', BITRIX_CLOUD_ADV_URL);
|
|
}
|
|
|
|
class Service
|
|
{
|
|
const SERVICE_URL = SEO_SERVICE_URL;
|
|
const REGISTER = "/oauth/register/";
|
|
const AUTHORIZE = "/register/";
|
|
const REDIRECT_URI = "/bitrix/tools/seo_client.php";
|
|
|
|
const SERVICE_AUTH_CACHE_TLL = 86400;
|
|
const SERVICE_AUTH_CACHE_TLL_ERROR = 3600;
|
|
const SERVICE_AUTH_CACHE_ID = 'seo|service_auth';
|
|
const SERVICE_AUTH_CACHE_ID_ERROR = 'seo|service_auth_error';
|
|
|
|
const CLIENT_LIST_CACHE_TLL = 86400;
|
|
const CLIENT_LIST_CACHE_ID = 'seo|client_list|2';
|
|
|
|
const CLIENT_TYPE_SINGLE = 'S';
|
|
const CLIENT_TYPE_MULTIPLE = 'M';
|
|
const CLIENT_TYPE_COMPATIBLE = 'C';
|
|
|
|
protected static $engine = null;
|
|
protected static $auth = null;
|
|
protected static $clientList = null;
|
|
|
|
/**
|
|
* CAn connect to seoproxy?
|
|
* @return bool
|
|
*/
|
|
public static function isRegistered()
|
|
{
|
|
return static::getEngine() && static::getEngine()->isRegistered();
|
|
}
|
|
|
|
/**
|
|
* Get client info
|
|
* @use \Bitrix\Seo\Service::getClientList(...)
|
|
*
|
|
* @param string $engineCode Provider code.
|
|
* @return boolean|array
|
|
* @deprecated
|
|
*/
|
|
public static function getAuth(string $engineCode)
|
|
{
|
|
global $CACHE_MANAGER;
|
|
if (static::$auth === null)
|
|
{
|
|
if ($CACHE_MANAGER->Read(static::SERVICE_AUTH_CACHE_TLL, static::SERVICE_AUTH_CACHE_ID))
|
|
{
|
|
static::$auth = $CACHE_MANAGER->Get(static::SERVICE_AUTH_CACHE_ID);
|
|
}
|
|
elseif (!$CACHE_MANAGER->Read(static::SERVICE_AUTH_CACHE_TLL_ERROR, static::SERVICE_AUTH_CACHE_ID_ERROR))
|
|
{
|
|
static::$auth = static::getEngine()?->getInterface()?->getClientInfo();
|
|
if (!static::$auth)
|
|
{
|
|
static::$auth = false;
|
|
$CACHE_MANAGER->Read(static::SERVICE_AUTH_CACHE_TLL_ERROR, static::SERVICE_AUTH_CACHE_ID_ERROR);
|
|
$CACHE_MANAGER->Set(static::SERVICE_AUTH_CACHE_ID_ERROR, static::$auth);
|
|
}
|
|
else
|
|
{
|
|
$CACHE_MANAGER->Set(static::SERVICE_AUTH_CACHE_ID, static::$auth);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
static::$auth = false;
|
|
}
|
|
}
|
|
|
|
return static::$auth["engine"][$engineCode] ?? false;
|
|
}
|
|
|
|
/**
|
|
* Get clients list
|
|
* @param string|bool $engineCode Provider code.
|
|
* @return array
|
|
* @throws SystemException
|
|
*/
|
|
public static function getClientList($engineCode = false, string $type = null)
|
|
{
|
|
if (static::$clientList == null)
|
|
{
|
|
$cache = Application::getInstance()->getManagedCache();
|
|
if ($cache->read(static::CLIENT_LIST_CACHE_TLL, static::CLIENT_LIST_CACHE_ID))
|
|
{
|
|
static::$clientList = $cache->get(static::CLIENT_LIST_CACHE_ID);
|
|
static::$clientList = is_array(static::$clientList) ? static::$clientList : [];
|
|
}
|
|
else
|
|
{
|
|
$request = Request::create($type);
|
|
$clientDataProvider = static::getEngine($request)?->getInterface();
|
|
if (!$clientDataProvider)
|
|
{
|
|
return [];
|
|
}
|
|
|
|
$result = $clientDataProvider->getClientList();
|
|
if (!is_array($result)) // backward compatibility
|
|
{
|
|
$result = [];
|
|
$data = $clientDataProvider->getClientInfo();
|
|
if (is_array($data))
|
|
{
|
|
foreach ($data as $code => $client)
|
|
{
|
|
$data['proxy_client_type'] = static::CLIENT_TYPE_COMPATIBLE;
|
|
$data['engine_code'] = $code;
|
|
$data['proxy_client_id'] = null;
|
|
$result[] = $data;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$result = $result['items'];
|
|
}
|
|
$cache->set(static::CLIENT_LIST_CACHE_ID, $result);
|
|
static::$clientList = $result;
|
|
}
|
|
}
|
|
if ($engineCode)
|
|
{
|
|
return array_filter(static::$clientList, function ($item) use ($engineCode)
|
|
{
|
|
return $item['engine_code'] == $engineCode;
|
|
});
|
|
}
|
|
|
|
return static::$clientList;
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @use \Bitrix\Seo\Service::clearClientsCache()
|
|
* @deprecated
|
|
*/
|
|
public static function clearLocalAuth()
|
|
{
|
|
global $CACHE_MANAGER;
|
|
|
|
$CACHE_MANAGER->Clean(static::SERVICE_AUTH_CACHE_ID);
|
|
|
|
static::$auth = null;
|
|
}
|
|
|
|
/**
|
|
* Clear clients list cache
|
|
* @param string|null $engine Engine code.
|
|
* @param int|null $clientId Proxy client id.
|
|
* @return void
|
|
* @throws SystemException
|
|
*/
|
|
public static function clearClientsCache($engine = null, $clientId = null)
|
|
{
|
|
$cache = Application::getInstance()->getManagedCache();
|
|
$cache->Clean(static::CLIENT_LIST_CACHE_ID);
|
|
$cache->Clean(static::SERVICE_AUTH_CACHE_ID);
|
|
$cache->Clean(static::SERVICE_AUTH_CACHE_ID_ERROR);
|
|
|
|
if ($engine && is_string($engine))
|
|
{
|
|
[$group, $type] = explode('.', $engine, 2);
|
|
if ($group == \Bitrix\Seo\Retargeting\Service::GROUP)
|
|
{
|
|
$service = AdsAudience::getService();
|
|
$service->setClientId($clientId);
|
|
$account = $service->getAccount($type);
|
|
if ($account)
|
|
{
|
|
$account->clearCache();
|
|
}
|
|
}
|
|
}
|
|
|
|
static::$clientList = null;
|
|
static::$auth = null;
|
|
}
|
|
|
|
/**
|
|
* @param string $engineCode Provider code.
|
|
* @param bool $localOnly Do not delete client in seoproxy service.
|
|
* @return void
|
|
* @use \Bitrix\Seo\Service::clearAuthForClient(...)
|
|
* @throws SystemException
|
|
* @deprecated
|
|
*/
|
|
public static function clearAuth($engineCode, $localOnly = false)
|
|
{
|
|
static::clearClientsCache($engineCode);
|
|
|
|
if (!$localOnly)
|
|
{
|
|
static::getEngine()?->getInterface()?->clearClientAuth($engineCode);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove auth for a client
|
|
* @param array $client Client data.
|
|
* @param bool $localOnly Only clear cache.
|
|
* @return void
|
|
* @throws SystemException
|
|
*/
|
|
public static function clearAuthForClient($client, $localOnly = false)
|
|
{
|
|
if (!$localOnly)
|
|
{
|
|
static::getEngine()?->getInterface()?->clearClientAuth($client['engine_code'], $client['proxy_client_id']);
|
|
}
|
|
static::clearClientsCache($client['engine_code'], $client['proxy_client_id']);
|
|
}
|
|
|
|
/**
|
|
* Set access settings
|
|
* @param array $accessParams Access params.
|
|
* @return void
|
|
* @throws SystemException
|
|
*/
|
|
protected static function setAccessSettings(array $accessParams): void
|
|
{
|
|
if (static::isRegistered())
|
|
{
|
|
$id = static::getEngine()->getId();
|
|
|
|
$result = SearchEngineTable::update($id, [
|
|
"CLIENT_ID" => $accessParams["client_id"],
|
|
"CLIENT_SECRET" => $accessParams["client_secret"],
|
|
"SETTINGS" => "",
|
|
]);
|
|
}
|
|
else
|
|
{
|
|
$result = SearchEngineTable::add([
|
|
"CODE" => Bitrix::ENGINE_ID,
|
|
"NAME" => "Bitrix",
|
|
"ACTIVE" => SearchEngineTable::ACTIVE,
|
|
"CLIENT_ID" => $accessParams["client_id"],
|
|
"CLIENT_SECRET" => $accessParams["client_secret"],
|
|
"REDIRECT_URI" => static::getRedirectUri(),
|
|
]);
|
|
}
|
|
|
|
if ($result->isSuccess())
|
|
{
|
|
static::clearAuth(Bitrix::ENGINE_ID, true);
|
|
static::$engine = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return Bitrix|null
|
|
* @throws LoaderException
|
|
*/
|
|
public static function getEngine(?Request $request = null): ?Bitrix
|
|
{
|
|
if (!Loader::includeModule("socialservices"))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (!static::$engine)
|
|
{
|
|
static::$engine = new Bitrix();
|
|
|
|
if ($request)
|
|
{
|
|
static::$engine->setAuthSettings(['PROXY_URL' => $request->getProxyUrl()]);
|
|
}
|
|
}
|
|
|
|
return static::$engine;
|
|
}
|
|
|
|
/**
|
|
* Try to register at external seoproxy service
|
|
*
|
|
* @return void
|
|
* @throws SystemException
|
|
*/
|
|
public static function register(string $serviceUrl = ''): void
|
|
{
|
|
static::clearClientsCache();
|
|
|
|
$httpClient = new HttpClient();
|
|
|
|
$queryParams = [
|
|
"key" => static::getLicense(),
|
|
"scope" => static::getEngine()?->getInterface()?->getScopeEncode(),
|
|
"redirect_uri" => static::getRedirectUri(),
|
|
];
|
|
|
|
$serviceUrl = $serviceUrl ?: static::SERVICE_URL;
|
|
|
|
$result = $httpClient->post($serviceUrl . static::REGISTER, $queryParams);
|
|
|
|
try
|
|
{
|
|
$result = Json::decode($result);
|
|
}
|
|
catch (\Exception $e)
|
|
{
|
|
$result = [
|
|
'error' => $e->getCode() . ': ' . $e->getMessage(),
|
|
];
|
|
}
|
|
|
|
if (isset($result['error']))
|
|
{
|
|
throw new SystemException($result['error']);
|
|
}
|
|
|
|
static::setAccessSettings($result);
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @throws SystemException
|
|
*/
|
|
public static function unregister()
|
|
{
|
|
if (static::isRegistered())
|
|
{
|
|
$id = static::getEngine()->getId();
|
|
SearchEngineTable::delete($id);
|
|
static::clearClientsCache();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public static function getAuthorizeLink()
|
|
{
|
|
return static::SERVICE_URL . static::AUTHORIZE;
|
|
}
|
|
|
|
/**
|
|
* @param string $engine Provider code.
|
|
* @param bool $clientType Client type.
|
|
* @return array
|
|
* @throws \Bitrix\Main\LoaderException
|
|
*/
|
|
public static function getAuthorizeData($engine, $clientType = false): array
|
|
{
|
|
$checkKey = "";
|
|
$session = Application::getInstance()
|
|
->getSession()
|
|
;
|
|
|
|
if (Loader::includeModule("socialservices") && $session->isAccessible())
|
|
{
|
|
$checkKey = \CSocServAuthManager::GetUniqueKey();
|
|
}
|
|
|
|
$clientType = $clientType ?: Service::CLIENT_TYPE_COMPATIBLE;
|
|
|
|
return [
|
|
"action" => "authorize",
|
|
"type" => $clientType,
|
|
"engine" => $engine,
|
|
"client_id" => static::getEngine()?->getClientId(),
|
|
"client_secret" => static::getEngine()?->getClientSecret(),
|
|
"key" => static::getLicense(),
|
|
"check_key" => urlencode($checkKey),
|
|
"redirect_uri" => static::getRedirectUri(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
protected static function getRedirectUri(): string
|
|
{
|
|
$request = Context::getCurrent()->getRequest();
|
|
|
|
$host = $request->getHttpHost();
|
|
$port = (int)$request->getServerPort();
|
|
$host .= ($port && $port !== 80 && $port !== 443) ? ":{$port}" : '';
|
|
|
|
$isHttps = $request->isHttps();
|
|
|
|
return ($isHttps ? 'https' : 'http') . '://' . $host . static::REDIRECT_URI;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
protected static function getLicense(): string
|
|
{
|
|
return md5(LICENSE_KEY);
|
|
}
|
|
|
|
/**
|
|
* If site change domain - need update engine
|
|
* @param array $domains
|
|
* @throws \Exception
|
|
*/
|
|
public static function changeRegisteredDomain(array $domains = []): void
|
|
{
|
|
if (!self::isRegistered())
|
|
{
|
|
return;
|
|
}
|
|
if (!$engine = static::getEngine())
|
|
{
|
|
return;
|
|
}
|
|
|
|
$newRedirectUri = static::getRedirectUri();
|
|
if (!empty($domains))
|
|
{
|
|
$newRedirectUri = str_replace($domains['old_domain'], $domains['new_domain'], $newRedirectUri);
|
|
}
|
|
|
|
SearchEngineTable::update($engine->getId(), [
|
|
'REDIRECT_URI' => $newRedirectUri,
|
|
]);
|
|
}
|
|
}
|