Add (article): ai gen, front views
This commit is contained in:
53
app/Helpers/FirstParty/OSSUploader/OSSUploader.php
Normal file
53
app/Helpers/FirstParty/OSSUploader/OSSUploader.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers\FirstParty\OSSUploader;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class OSSUploader
|
||||
{
|
||||
public static function readJson($storage_driver, $relative_directory, $filename)
|
||||
{
|
||||
$filepath = rtrim($relative_directory, '/').'/'.$filename;
|
||||
|
||||
try {
|
||||
$jsonContent = Storage::disk($storage_driver)->get($filepath);
|
||||
|
||||
$decodedJson = json_decode($jsonContent, false, 512);
|
||||
|
||||
return $decodedJson;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function uploadJson($storage_driver, $relative_directory, $filename, $jsonData)
|
||||
{
|
||||
$jsonString = json_encode($jsonData, JSON_PRETTY_PRINT);
|
||||
|
||||
try {
|
||||
return self::uploadFile($storage_driver, $relative_directory, $filename, $jsonString);
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static function uploadFile($storage_driver, $relative_directory, $filename, $file)
|
||||
{
|
||||
$filepath = rtrim($relative_directory, '/').'/'.$filename;
|
||||
|
||||
// if(!Storage::disk($storage_driver)->exists($relative_directory))
|
||||
// {
|
||||
// Storage::disk($storage_driver)->makeDirectory($relative_directory);
|
||||
// }
|
||||
|
||||
return Storage::disk($storage_driver)->put($filepath, $file);
|
||||
}
|
||||
}
|
||||
90
app/Helpers/FirstParty/OpenAI/OpenAI.php
Normal file
90
app/Helpers/FirstParty/OpenAI/OpenAI.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers\FirstParty\OpenAI;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class OpenAI
|
||||
{
|
||||
public static function writeArticle($title, $description, $article_type, $min, $max)
|
||||
{
|
||||
$system_prompt = "
|
||||
Using the general article structure, please create a Markdown format article on the topic given. The article should prioritize accuracy and provide genuine value to readers. Avoid making assumptions or adding unverified facts. Ensure the article is between {$min}-{$max} words. Write with 8th & 9th grade US english standard.\n\n
|
||||
Structure:\n\n
|
||||
Title\n
|
||||
Provide a headline that captures the essence of the article's focus and is tailored to the reader's needs.\n\n
|
||||
Introduction\n
|
||||
Offer a brief overview or background of the topic, ensuring it's engaging and invites readers to continue reading.\n\n
|
||||
Main Body\n\n
|
||||
Subsection\n
|
||||
Introduce foundational information about the topic, ensuring content is accurate and based on known facts. Avoid generic or speculative statements.\n\n
|
||||
Subsection (if applicable)\n
|
||||
If helpful, use Markdown to create tables to convey comparison of data. Ensure data is accurate and relevant to the reader.\n\n
|
||||
Subsection\n
|
||||
Dive deep into primary elements or facets of the topic, ensuring content is factual and offers value.\n\n
|
||||
Subsection\n
|
||||
Discuss real-world applications or significance, highlighting practical implications or actionable insights for the reader.\n\n
|
||||
Subsection (optional)\n
|
||||
Provide context or relate the topic to relevant past events or trends, making it relatable and more comprehensive.\n\n
|
||||
Subsection (if applicable)\n
|
||||
Predict outcomes, trends, or ramifications, but ensure predictions are rooted in known information or logical reasoning.\n\n
|
||||
Subsection\n
|
||||
Summarise key points or lessons, ensuring they resonate with the initial objectives of the article and provide clear takeaways.\n\n
|
||||
Conclusion\n
|
||||
Revisit main points and offer final thoughts or recommendations that are actionable and beneficial to the reader.\n\n
|
||||
FAQs\n
|
||||
Address anticipated questions or misconceptions about the topic. Prioritize questions that readers are most likely to have and provide clear, concise answers based on factual information.\n
|
||||
Q: Question\n
|
||||
A: Answer\n
|
||||
";
|
||||
|
||||
$user_prompt = "Title: {$title}\nDescription: {$description}\nArticleType: {$article_type}";
|
||||
|
||||
return self::chatCompletion($system_prompt, $user_prompt, 'gpt-3.5-turbo');
|
||||
|
||||
}
|
||||
|
||||
public static function suggestArticleTitles($current_title, $supporting_data, $suggestion_counts)
|
||||
{
|
||||
$system_prompt = "Based on provided article title, identify the main keyword in 1-2 words. Once identified, use the main keyword only to generate {$suggestion_counts} easy-to-read unique, helpful title articles.\n\n
|
||||
Requirements:\n
|
||||
2 descriptive photos keywords to represent article title when put together side-by-side\n
|
||||
No realtime information required\n
|
||||
No guides and how tos\n
|
||||
No punctuation in titles especially colons :\n
|
||||
90-130 characters\n\n
|
||||
|
||||
return in following json format {\"main_keyword\":\"(Main Keyword)\",\"suggestions\":[{\"title\":\"(Title in 90-130 letters)\",\"short_title\":\"(Short Title in 30-40 letters)\",\"article_type\":\"(How-tos|Guides|Interview|Review|Commentary|Feature|News|Editorial|Report|Research|Case-study|Overview|Tutorial|Update|Spotlight|Insights)\",\"description\":\"(SEO description based on main keyword)\",\"photo_keywords\":[\"photo keyword 1\",\"photo keyword 2\"]}]}";
|
||||
|
||||
$user_prompt = "Article Title: {$current_title}";
|
||||
|
||||
$reply = self::chatCompletion($system_prompt, $current_title, 'gpt-3.5-turbo');
|
||||
|
||||
try {
|
||||
return json_decode($reply, false);
|
||||
} catch (Exception $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function chatCompletion($system_prompt, $user_prompt, $model)
|
||||
{
|
||||
$response = Http::timeout(500)->withToken(config('platform.ai.openai.api_key'))
|
||||
->post('https://api.openai.com/v1/chat/completions', [
|
||||
'model' => $model,
|
||||
'max_tokens' => 2500,
|
||||
'messages' => [
|
||||
['role' => 'user', 'content' => $system_prompt.' '.$user_prompt],
|
||||
],
|
||||
]);
|
||||
|
||||
$json_response = json_decode($response->body());
|
||||
|
||||
$reply = $json_response?->choices[0]?->message?->content;
|
||||
|
||||
return $reply;
|
||||
|
||||
}
|
||||
}
|
||||
46
app/Helpers/Global/geo_helper.php
Normal file
46
app/Helpers/Global/geo_helper.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
if (! function_exists('get_current_ip')) {
|
||||
function get_current_ip()
|
||||
{
|
||||
$ip = null;
|
||||
|
||||
if (app()->environment() == 'local') {
|
||||
return config('platform.general.dev_default_ip');
|
||||
}
|
||||
|
||||
if (getenv('HTTP_CF_CONNECTING_IP')) {
|
||||
$ip = getenv('HTTP_CF_CONNECTING_IP');
|
||||
} elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
|
||||
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
|
||||
}
|
||||
|
||||
if (! is_empty($ip)) {
|
||||
return $ip;
|
||||
}
|
||||
|
||||
$ip_add_set = null;
|
||||
|
||||
if (getenv('HTTP_CLIENT_IP')) {
|
||||
$ip_add_set = getenv('HTTP_CLIENT_IP');
|
||||
} elseif (getenv('HTTP_X_FORWARDED_FOR')) {
|
||||
$ip_add_set = getenv('HTTP_X_FORWARDED_FOR');
|
||||
} elseif (getenv('HTTP_X_FORWARDED')) {
|
||||
$ip_add_set = getenv('HTTP_X_FORWARDED');
|
||||
} elseif (getenv('HTTP_FORWARDED_FOR')) {
|
||||
$ip_add_set = getenv('HTTP_FORWARDED_FOR');
|
||||
} elseif (getenv('HTTP_FORWARDED')) {
|
||||
$ip_add_set = getenv('HTTP_FORWARDED');
|
||||
} elseif (getenv('REMOTE_ADDR')) {
|
||||
$ip_add_set = getenv('REMOTE_ADDR');
|
||||
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
||||
$ip_add_set = $_SERVER['REMOTE_ADDR'];
|
||||
} else {
|
||||
$ip_add_set = '127.0.0.0';
|
||||
}
|
||||
|
||||
$ip_add_set = explode(',', $ip_add_set);
|
||||
|
||||
return $ip_add_set[0];
|
||||
}
|
||||
}
|
||||
5
app/Helpers/Global/helpers.php
Normal file
5
app/Helpers/Global/helpers.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
require 'string_helper.php';
|
||||
require 'geo_helper.php';
|
||||
require 'platform_helper.php';
|
||||
13
app/Helpers/Global/platform_helper.php
Normal file
13
app/Helpers/Global/platform_helper.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
if (! function_exists('get_slack_channel_by_env')) {
|
||||
|
||||
function get_slack_channel_by_env($slack_channel = 'slack')
|
||||
{
|
||||
if (app()->environment() == 'local') {
|
||||
return config("platform.notifications.{$slack_channel}.development_channel");
|
||||
} else {
|
||||
return config("platform.notifications.{$slack_channel}.production_channel");
|
||||
}
|
||||
}
|
||||
}
|
||||
120
app/Helpers/Global/string_helper.php
Normal file
120
app/Helpers/Global/string_helper.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
if (! function_exists('epoch_now_timestamp')) {
|
||||
function epoch_now_timestamp()
|
||||
{
|
||||
return (int) round(microtime(true) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('unslug')) {
|
||||
function unslug($slug, $delimiter = '-')
|
||||
{
|
||||
return ucwords(str_replace($delimiter, ' ', $slug));
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('str_slug')) {
|
||||
function str_slug($string, $delimiter = '-')
|
||||
{
|
||||
return Str::of(trim($string))->slug($delimiter);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('str_first_sentence')) {
|
||||
function str_first_sentence($str)
|
||||
{
|
||||
// Split the string at ., !, or ?
|
||||
$sentences = preg_split('/(\.|!|\?)(\s|$)/', $str, 2);
|
||||
|
||||
// Return the first part of the array if available
|
||||
if (isset($sentences[0])) {
|
||||
return trim($sentences[0]);
|
||||
}
|
||||
|
||||
// If no sentence ending found, return the whole string
|
||||
return $str;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (! function_exists('is_empty')) {
|
||||
/**
|
||||
* A better function to check if a value is empty or null. Strings, arrays, and Objects are supported.
|
||||
*
|
||||
* @param mixed $value
|
||||
*/
|
||||
function is_empty($value): bool
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_string($value)) {
|
||||
if ($value === '') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
if (count($value) === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_object($value)) {
|
||||
$value = (array) $value;
|
||||
|
||||
if (count($value) === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_country_name_by_iso')) {
|
||||
function get_country_name_by_iso($country_iso)
|
||||
{
|
||||
if (! is_empty($country_iso)) {
|
||||
|
||||
$country_iso = strtoupper($country_iso);
|
||||
|
||||
try {
|
||||
return config("platform.country_codes.{$country_iso}")['name'];
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 'International';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_country_emoji_by_iso')) {
|
||||
function get_country_emoji_by_iso($country_iso)
|
||||
{
|
||||
if (! is_empty($country_iso)) {
|
||||
|
||||
$country_iso = strtoupper($country_iso);
|
||||
|
||||
try {
|
||||
return config("platform.country_codes.{$country_iso}")['emoji'];
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return '🌎';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('str_random')) {
|
||||
function str_random($length = 10)
|
||||
{
|
||||
return Str::random($length);
|
||||
}
|
||||
}
|
||||
580
app/Helpers/ThirdParty/DFS/AbstractModel.php
vendored
Normal file
580
app/Helpers/ThirdParty/DFS/AbstractModel.php
vendored
Normal 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 ?? [];
|
||||
}
|
||||
}
|
||||
203
app/Helpers/ThirdParty/DFS/SettingSerpLiveAdvanced.php
vendored
Normal file
203
app/Helpers/ThirdParty/DFS/SettingSerpLiveAdvanced.php
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers\ThirdParty\DFS;
|
||||
|
||||
class SettingSerpLiveAdvanced extends AbstractModel
|
||||
{
|
||||
protected $method = 'POST';
|
||||
|
||||
protected $isSupportedMerge = true;
|
||||
|
||||
protected $pathToMainData = 'tasks->{$postID}->result';
|
||||
|
||||
protected $requestToFunction = 'serp/{$se}/{$seType}/live/advanced';
|
||||
|
||||
protected $resultShouldBeTransformedToArray = true;
|
||||
|
||||
protected $jsonContainVariadicType = true;
|
||||
|
||||
protected $pathsToVariadicTypesAndValue = ['tasks->(:number)->result->(:number)->items->(:number)' => 'type'];
|
||||
|
||||
protected $useNewMapper = true;
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setUrl(string $url)
|
||||
{
|
||||
$this->payload['url'] = $url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setLanguageCode(string $langCode)
|
||||
{
|
||||
$this->payload['language_code'] = $langCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setKeyword(string $keyword)
|
||||
{
|
||||
$this->payload['keyword'] = $keyword;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setPriority(string $priority)
|
||||
{
|
||||
$this->payload['priority'] = $priority;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setLocationName(string $locationName)
|
||||
{
|
||||
$this->payload['location_name'] = $locationName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setLocationCode(int $locationCode)
|
||||
{
|
||||
$this->payload['location_code'] = $locationCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setLocationCoordinate(string $locationCoordinate)
|
||||
{
|
||||
$this->payload['location_coordinate'] = $locationCoordinate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setLanguageName(string $languageName)
|
||||
{
|
||||
$this->payload['language_name'] = $languageName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setDevice(string $device)
|
||||
{
|
||||
$this->payload['device'] = $device;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setOs(string $os)
|
||||
{
|
||||
$this->payload['os'] = $os;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setSeDomain(string $seDomain)
|
||||
{
|
||||
$this->payload['se_domain'] = $seDomain;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setDepth(int $depth)
|
||||
{
|
||||
$this->payload['depth'] = $depth;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setSearchParam(string $searchParam)
|
||||
{
|
||||
$this->payload['search_param'] = $searchParam;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setTag(string $tag)
|
||||
{
|
||||
$this->payload['tag'] = $tag;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setSeType(string $seType)
|
||||
{
|
||||
if (! in_array($seType, $this->seTypes)) {
|
||||
throw new \Exception('Provided se type not allowed');
|
||||
}
|
||||
|
||||
$this->requestToFunction = str_replace('{$seType}', $seType, $this->requestToFunction);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setSe(string $seName)
|
||||
{
|
||||
$this->requestToFunction = str_replace('{$se}', $seName, $this->requestToFunction);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function get(): \DFSClientV3\Entity\Custom\SettingSerpLiveAdvancedEntityMain
|
||||
{
|
||||
return parent::get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getAfterMerge(array $modelPool)
|
||||
{
|
||||
return parent::getAfterMerge($modelPool); // TODO: Change the autogenerated stub
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user