Add (article): ai gen, front views

This commit is contained in:
2023-09-24 22:53:40 +08:00
parent 18705bd5e4
commit 322d680961
115 changed files with 9710 additions and 201 deletions

View File

@@ -0,0 +1,580 @@
<?php
namespace App\Helpers\ThirdParty\DFS;
use DFSClientV3\Bootstrap\Application;
use DFSClientV3\Models\DataMapper;
use DFSClientV3\Services\HttpClient\Handlers\Responses;
use DFSClientV3\Services\HttpClient\HttpClient;
abstract class AbstractModel
{
/**
* @var null|int timeout for http request
*/
protected $timeOut = null;
protected $apiVersion = null;
/**
* @var string | null url to DataForSeo API
*/
protected $url = null;
/**
* @var int|null PostId is needed for a request, for more information check an example or DFSApi
*/
protected $postId = null;
/**
* @var null This field is not working at the moment
*/
public $statusCode;
/**
* @var null This field is not working at the moment
*/
public $statusMessage;
/**
* @var array
*/
protected $headers = [];
/**
* @var null This field is not working at the moment
*/
protected $requiredField;
/**
* @var null This field is not working at the moment
*/
protected $mainData;
/**
* @var static RequestType, this param will be sent to DFS API, .xml, .gzip etc...
*/
protected $requestType;
/**
* @var string Method for http request. POST, GET , PUT, DELETE
*/
protected $method = 'POST';
/**
* This variable is required for all extended Classes from AbstractModel.
*
* @var null|string It is a name, when you want to send a request to api, use this param as an api endpoint, example: cmn_user
*/
protected $requestToFunction;
/**
* This variable is required for all extended Classes from AbstractModel
* example for path: results->0->related.
*
* results - is object link from DFSResponse
* 0 - is Index of array or postID
* related - is object link containing main data
*
* @var null|string It is a system variable, it contains a path to main data from response and creates iterable(IteratorAggregator) response.
*/
protected $pathToMainData = null;
/**
* @var bool If payload contains postId
*/
protected $isSupportedMerge = false;
/**
* @var null|string
*/
private $DFSLogin = null;
/**
* @var null|string
*/
private $DFSPassword = null;
public $response;
protected $application;
protected $config;
/**
* @var array
*/
protected $payload;
protected $isProcessed;
protected $mappedMainModel;
protected $seTypes = ['organic', 'maps', 'local_finder', 'news', 'images', 'search_by_image'];
/**
* @var bool
*/
protected $jsonContainVariadicType = false;
/**
* @var array
*/
protected $pathsToVariadicTypesAndValue = [];
/**
* @var array
*/
protected $customFunctionForPaths = [];
/**
* @var array
*/
protected $pathsToDictionary = [];
/**
* @var bool Temp variable, for detect when use new mapper
*/
protected $useNewMapper = false;
/**
* new version of DataForSeo has two variations of result
* 1. Object contains other objects for response.
* 2. Object contains other objects, but they is iterable.
*
* if model has property $resultShouldBeTransformedToArray as true, result index will be transformed to array
*
* @var bool
*/
protected $resultShouldBeTransformedToArray = false;
public function __construct()
{
$this->application = Application::getInstance();
$this->config = $this->application->getConfig();
$this->initDefaultMethods();
}
/**
* @param $postID mixed
*/
public function setPostID($postID)
{
$this->postId = $postID;
return $this;
}
/**
* @param $headers array
*/
public function setHeaders($headers)
{
if (count($headers) > 0) {
foreach ($headers as $key => $value) {
$this->config['headers'][$key] = $value;
}
}
return $this;
}
/**
* This method will run request to api.
*/
protected function get()
{
$response = $this->process();
// check if response contain valid json
$validResponse = json_decode($response->getResponse());
if (json_last_error() !== JSON_ERROR_NONE) {
$validResponse = ['status_code' => 50000, 'status_message' => 'error.'];
}
return $this->mapData(json_encode($validResponse), $response->getStatus());
}
/**
* @return mixed
*
* @throws \Exception
*/
public static function getAfterMerge(array $modelPool)
{
if (empty($modelPool)) {
throw new \Exception('Model pool can not be empty');
}
$payload = [];
$url = null;
$apiVersion = null;
$timeOut = null;
$login = null;
$password = null;
$method = null;
$requestToFunction = null;
$config = Application::getInstance()->getConfig();
$pathToMainData = null;
$resultShouldTransformedToArray = false;
$useNewMapper = false;
$isJsonContainVariadicType = false;
$pathsToVariadicTypesAndValue = [];
$customFunctionForPaths = [];
foreach ($modelPool as $key => $model) {
// kostyl, all variable will be rewrite every iteration
$url = $model->url;
$apiVersion = $model->apiVersion;
$timeOut = $model->timeOut;
$login = $model->DFSLogin;
$password = $model->DFSPassword;
$method = $model->method;
$requestToFunction = $model->requestToFunction;
$pathToMainData = $model->pathToMainData;
$resultShouldTransformedToArray = $model->resultShouldBeTransformedToArray;
$useNewMapper = $model->isUseNewMapper();
$isJsonContainVariadicType = $model->isJsonContainVariadicType();
$pathsToVariadicTypesAndValue = $model->getPathsToVariadicTypesAndValue();
$customFunctionForPaths = $model->getCustomFunctionForPaths();
if ($model->isSupportedMerge) {
if ($model->postId === null) {
$payload['json'][] = $model->payload;
}
if ($model->postId !== null) {
$payload['json'][$model->postId] = $model->payload;
}
} else {
throw new \Exception('Provided model '.get_class($model).' is not supported merge');
}
}
$payload['headers'] = $config['headers'];
$http = new HttpClient($url, $apiVersion, $timeOut, $login, $password);
$res = $http->sendSingleRequest($method, $requestToFunction, $payload);
// check if response contain valid json
$validResponse = json_decode($res->getResponse());
if (json_last_error() !== JSON_ERROR_NONE) {
$validResponse = ['status_code' => 50000, 'status_message' => 'error.'];
}
//get called class.
$calledClassNameWithNapeSpace = get_called_class();
$classNameArray = explode('\\', $calledClassNameWithNapeSpace);
//for php 7.3 can be use array_last_key
$classNameArray[count($classNameArray) - 1];
$mapper = new DataMapper($classNameArray[count($classNameArray) - 1], $res->getStatus(), $pathToMainData);
if ($useNewMapper) {
$paveDataOptions = new PaveDataOptions();
$paveDataOptions->setJson(json_encode($validResponse));
$paveDataOptions->setJsonContainVariadicType($isJsonContainVariadicType);
$paveDataOptions->setPathsToVariadicTypesAndValue($pathsToVariadicTypesAndValue);
$paveDataOptions->setCustomFunctionForPaths($customFunctionForPaths);
$mappedModel = $mapper->paveDataNew($paveDataOptions);
return $mappedModel;
}
$mappedModel = $mapper->paveData(json_encode($validResponse), null, $resultShouldTransformedToArray);
return $mappedModel;
}
/**
* @param array|AbstractModel[] $modelPool
* @return array|null
*/
public static function getAsync(array $modelPool, int $timeout = 100)
{
if (count($modelPool) > 100) {
return null;
}
$requestsPool = [];
$results = [];
$payload = [];
$url = null;
$apiVersion = null;
$timeOut = null;
$login = null;
$password = null;
$config = Application::getInstance()->getConfig();
$pathToMainData = null;
$resultShouldTransformedToArray = false;
$useNewMapper = false;
$isJsonContainVariadicType = false;
$pathsToVariadicTypesAndValue = [];
$customFunctionForPaths = [];
$pathsToDictionary = [];
foreach ($modelPool as $key => $model) {
// kostyl, all variable will be rewrite every iteration
$url = $model->url;
$apiVersion = $model->apiVersion;
$login = $model->DFSLogin;
$password = $model->DFSPassword;
$pathToMainData = $model->pathToMainData;
$resultShouldTransformedToArray = $model->resultShouldBeTransformedToArray;
$useNewMapper = $model->isUseNewMapper();
$isJsonContainVariadicType = $model->isJsonContainVariadicType();
$pathsToVariadicTypesAndValue = $model->getPathsToVariadicTypesAndValue();
$customFunctionForPaths = $model->getCustomFunctionForPaths();
$pathsToDictionary = $model->getPathsToDictionary();
$payload['json'][] = $model->getPayload();
$payload['headers'] = $config['headers'];
$requestsPool[$key]['method'] = $model->getHttpMethod();
$requestsPool[$key]['url'] = $model->getRequestToFunction();
$requestsPool[$key]['params'] = $payload;
$requestsPool[$key]['pathToMainData'] = $model->getPathToMainData();
}
$http = new HttpClient($url, $apiVersion, $timeout, $login, $password);
$responses = $http->sendAsyncRequests($requestsPool, null);
foreach ($responses as $response) {
/**
* @var Responses $response
*/
//get called class.
$calledClassNameWithNapeSpace = get_called_class();
$classNameArray = explode('\\', $calledClassNameWithNapeSpace);
//for php 7.3 can be use array_last_key
$classNameArray[count($classNameArray) - 1];
$mapper = new DataMapper($classNameArray[count($classNameArray) - 1], $response->getStatus(), $pathToMainData);
if ($useNewMapper) {
$paveDataOptions = new PaveDataOptions();
$paveDataOptions->setJson($response->getResponse());
$paveDataOptions->setJsonContainVariadicType($isJsonContainVariadicType);
$paveDataOptions->setPathsToDictionary($pathsToDictionary);
$paveDataOptions->setPathsToVariadicTypesAndValue($pathsToVariadicTypesAndValue);
$paveDataOptions->setCustomFunctionForPaths($customFunctionForPaths);
$mappedModel = $mapper->paveDataNew($paveDataOptions);
$results[] = $mappedModel;
}
if (! $useNewMapper) {
$results[] = $mapper->paveData($response->getResponse(), null, $resultShouldTransformedToArray);
}
}
return $results;
}
/**
* @return \DFSClientV3\Services\HttpClient\Handlers\Responses
*/
public function process()
{
$http = new HttpClient($this->url, $this->apiVersion, $this->timeOut, $this->DFSLogin, $this->DFSPassword);
$payload = [];
if (! $this->application) {
dd('DFSClient was not init, add to your code: $DFSClient = new DFSClient() ');
}
if (! $this->requestToFunction) {
dd('requestFunction can not be null, set this field in your model: '.get_called_class());
}
if ($this->postId === null) {
$payload['json'][0] = $this->payload;
}
if ($this->postId != null) {
$payload['json'][$this->postId] = $this->payload;
}
$payload['headers'] = $this->config['headers'];
$res = $http->sendSingleRequest($this->method, $this->requestToFunction, $payload);
return $res;
}
public function getAsJson()
{
$result = $this->process()->getResponse();
return $result;
}
/**
* @return string|null
*/
public function getPathToMainData()
{
return $this->pathToMainData;
}
/**
* @return mixed
*/
public function getCalledClass()
{
$calledClassNameWithNapeSpace = get_called_class();
$classNameArray = explode('\\', $calledClassNameWithNapeSpace);
//for php 7.3 can be use array_last_key
return $classNameArray[count($classNameArray) - 1];
}
public function setOpt()
{
}
public function setLogin(string $newLogin)
{
$this->DFSLogin = $newLogin;
return $this;
}
public function setPassword(string $newPassword)
{
$this->DFSPassword = $newPassword;
return $this;
}
/**
* @param bool $isSuccesful
*
* return mixed;
*/
protected function mapData(string $json, bool $isSuccesful = false)
{
$mapper = new DataMapper($this->getCalledClass(), $isSuccesful, $this->pathToMainData);
if ($this->useNewMapper) {
$paveDataOptions = new PaveDataOptions();
$paveDataOptions->setJson($json);
$paveDataOptions->setJsonContainVariadicType($this->isJsonContainVariadicType());
$paveDataOptions->setPathsToVariadicTypesAndValue($this->getPathsToVariadicTypesAndValue());
$paveDataOptions->setPathsToDictionary($this->getPathsToDictionary());
$paveDataOptions->setCustomFunctionForPaths($this->getCustomFunctionForPaths());
$mappedModel = $mapper->paveDataNew($paveDataOptions);
return $mappedModel;
}
$mappedModel = $mapper->paveData($json, null, $this->resultShouldBeTransformedToArray);
return $mappedModel;
}
/**
* @return bool
*/
public function resultShouldBeTransformedToArray()
{
return $this->resultShouldBeTransformedToArray;
}
public function useSandbox(string $url = null)
{
$this->url = $this->config['sandboxUrl'];
}
/**
* @param $timeOut int
*/
public function setTimeOut(int $timeOut)
{
$this->timeOut = $timeOut;
return $this;
}
public function isJsonContainVariadicType(): bool
{
return $this->jsonContainVariadicType;
}
public function getPathsToVariadicTypesAndValue(): array
{
return $this->pathsToVariadicTypesAndValue;
}
public function getPathsToDictionary(): array
{
return $this->pathsToDictionary;
}
public function addCustomFunctionForPath(array $customFunction)
{
$this->customFunctionForPaths = array_merge($this->customFunctionForPaths, $customFunction);
return $this;
}
public function getCustomFunctionForPaths(): array
{
return $this->customFunctionForPaths;
}
private function initDefaultMethods()
{
$this->addCustomFunctionForPath($this->initCustomFunctionForPaths());
}
protected function initCustomFunctionForPaths(): array
{
return [];
}
public function isUseNewMapper(): bool
{
return $this->useNewMapper;
}
/**
* @return string
*/
public function getHttpMethod()
{
return $this->method;
}
/**
* @return string|null
*/
public function getRequestToFunction()
{
return $this->requestToFunction;
}
public function getPayload(): array
{
return $this->payload ?? [];
}
}